TypeScript:Element 隐式具有 RegExp 的'any'类型



所以,我想创建一个函数,该函数将获取持续时间字符串(例如12ms7.5 MIN400H(,解析它并将其转换为毫秒。

const units = {
MS: 1,
S: 1 * 1000,
MIN: 60 * 1 * 1000,
H: 60 * 60 * 1 * 1000
}
export function toMS(str: string): number {
let regex = /^(?<number>d+(?:.d+)?)(?:s*(?<unit>MS|S|MIN|H))?$/i
if (!regex.test(str)) {
throw new TypeError(`Expected a duration, got: ${str}`)
}
let match = str.match(regex)
let number = Number(match?.groups?.number)
let unit = (match?.groups?.unit || 'ms').toUpperCase()
return Math.floor(number * units[unit])
}

因此,函数toMS()接受一个字符串,测试提供的字符串是否有效(number+whitespace (optional)+unit abbr (optional)(,如果有效 - 使用str.match(regex)解析它。

一切正常,直到:units[unit]。它给了我一个错误:Element implicitly has an 'any' type because expression of type 'string' can't be used to index type.

我以前在函数参数和类构造函数中遇到过同样的错误,由于用户提供数据,因此很容易解决。但是现在我不知道如何解决这个问题,因为我不能强迫str.match(regex).groups.unit拥有像: 'MS | S | MIN | H这样的特定类型。

我知道也可以用"noImplicitAny": false创建tsconfig.json,但就我而言,这根本不好。

问题是 TypeScript 无法知道您的正则表达式是否真的与MS|S|MIN|H匹配。这是依赖类型的领域,而TypeScript还没有那么强大。

TypeScript 唯一知道的是,你匹配的将是一个string,因为match?.groups?.unit'ms'表达式都会产生string

你可以做的是让 TypeScript 知道你的units是一个键类型为string和值为number类型的对象,并检查你匹配的是否是units对象的属性。喜欢这个:

const units: { [k: string]: number } = { // letting TypeScript know
MS: 1,
S: 1 * 1000,
MIN: 60 * 1 * 1000,
H: 60 * 60 * 1 * 1000,
};
export function toMS(str: string): number {
const regex = /^(?<number>d+(?:.d+)?)(?:s*(?<unit>MS|S|MIN|H))?$/i;
if (!regex.test(str)) {
throw new TypeError(`Expected a duration, got: ${str}`);
}
const match = str.match(regex);
const number = Number(match?.groups?.number);
const unit = (match?.groups?.unit || 'ms').toUpperCase();
if (unit in units) { // checking whether your matched string is something you can handle, in runtime
return Math.floor(number * units[unit]);
} else {
throw new Error(`couldn't find units! :(`);
}
}

相关内容

  • 没有找到相关文章

最新更新