TypeScript中如何将字符串字面量类型转换为数字类型?能否实现Number<T>工具类型并扩展Add工具类型支持字符串字面量参数?
How to Convert String Literal Types to Numbers in TypeScript & Extend the Add Utility Type
当然有办法实现字符串字面量到数字类型的转换!咱们可以通过TypeScript的条件类型和模板字面量推断来构建你需要的Number<T>工具类型,之后再把它集成到你的Add类型里,让它同时支持数字和字符串参数。
1. Implementing the Number<T> Utility Type
首先,咱们来实现你要求的Number<T>:它会接收一个可转换为数字的字符串字面量,返回对应的数字类型;如果参数无法转成数字,就返回never。具体实现如下:
type Number<T extends string> = T extends `${infer N extends number}` ? N : never;
怎么工作的?
这里用到了TypeScript的模板字面量类型推断:${infer N extends number}会检查输入的字符串T是否符合数字字面量的格式,如果匹配成功,就把T推断为数字类型N并返回;如果不匹配(比如输入是'abc'这种非数字字符串),就返回never。
测试一下效果:
type Five = Number<'5'>; // 类型是 5 type Ten = Number<'10'>; // 类型是 10 type InvalidInput = Number<'hello'>; // 类型是 never
2. Extending the Add Utility Type to Support String Literals
接下来咱们改造你现有的Add类型,让它既能接受数字类型参数,也能接受合法的数字字符串字面量。首先咱们需要一个辅助类型ToNumber<T>,用来统一把输入(不管是数字还是字符串)转换成数字类型:
type ToNumber<T> = T extends number ? T : // 如果已经是数字,直接返回 T extends string ? Number<T> : // 如果是字符串,用上面的Number<T>转换 never; // 其他类型返回never
然后修改你的Add类型,先把两个参数都转换成数字,再执行原来的数组拼接逻辑:
// 保留你原来的createArray工具类型 type createArray<Len, Ele, Arr extends Ele[] = []> = Arr['length'] extends Len ? Arr : createArray<Len, Ele, [Ele, ...Arr]>; // 扩展后的Add类型 type Add<A, B> = ToNumber<A> extends infer NumA extends number ? ToNumber<B> extends infer NumB extends number ? [...createArray<NumA, 1>, ...createArray<NumB, 1>]['length'] : never : never;
测试扩展后的Add
现在不管是数字参数还是字符串参数,Add都能正常工作了:
type Answer1 = Add<3, 10>; // 类型是 13(原来的数字参数依然有效) type Answer2 = Add<'3', '10'>; // 类型是 13(支持字符串参数) type Answer3 = Add<'5', 7>; // 类型是 12(混合参数也没问题) type InvalidAdd = Add<'abc', 2>; // 类型是 never(无效输入返回never)
这样就完美实现了你想要的功能——既保留了原来Add对数字类型的支持,又扩展了对数字字符串字面量的处理,同时还保证了类型安全,无效输入会被标记为never。
内容的提问来源于stack exchange,提问作者Joji
相关产品推荐
相关产品推荐

