没有办法将任意字符串文本类型转换为数字文本类型(我通常称之为
StringToNumber<T>
)。最近有一个请求在
microsoft/TypeScript#47141,要求支持此功能,但被拒绝了。他们不想支持这个功能。还有一个仍未解决的问题
microsoft/TypeScript#26382,要求支持文本类型的任意数学运算,包括请求
StringToNumber<T>
,也许还有一些希望?但我不指望它。
如果您只关心小于1000的非负整数(由于尾递归消除的限制),则可以通过元组操作自己实现,类似于您正在执行的Add
操作:
type StringToNumber<T extends string, A extends any[] = []> =
T extends keyof [0, ...A] ? A['length'] : StringToNumber<T, [0, ...A]>
你可以看到它的工作:
type Thirteen = StringToNumber<"13">
// type Thirteen = 13
这个跟Add
一样脆弱,如果你传入意外的东西,可能会导致编译器性能变慢或出错:
// type Nope = Add<0.4, 10>
// Type instantiation is excessively deep and possibly infinite.(2589)
因此,您可以尝试将输入限制为有效的数字字符串:
type Digit = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" | "";
type NonZero = Exclude<Digit, "0" | "">
type LessThanAThousand = "0" | `${NonZero}${Digit}${Digit}`
type StringToNumber<T extends LessThanAThousand, A extends any[] = []> =
T extends LessThanAThousand ? T extends keyof [0, ...A] ?
A['length'] : StringToNumber<T, [0, ...A]> : never;
type Oops = StringToNumber<"0.4"> // error
// ----------------------> ~~~~~
// Type '"0.4"' does not satisfy the constraint 'LessThanAThousand'.(2344)
看起来没问题。
但是,除非有非常好的用例,否则我不会推荐这种做法。 Add
实用类型本身并不是 TS 团队认为值得支持的东西(这可能就是为什么 ms/TS#47141 被拒绝的原因)。
代码的 Playground 链接
minus
是不可能的,因为您可以轻松地向数组中添加更多元素,但似乎没有简单的方法从数组中弹出元素。 - Joji