如何在TypeScript中将`${number}`类型转为字符串字面量'${number}'?
TypeScript:将模板字面量类型转换为纯字符串字面量类型
问题描述
假设我们有如下联合类型Foo:
type Foo = 'apple' | `a.${number}` | `a.${number}.c`
想要将其转换为Boo类型,让原本带${number}的模板字面量变成纯字符串字面量形式:
type Boo = ReplaceTemplateWithLiteral<Foo> // 期望得到:'apple' | 'a.${number}' | 'a.${number}.c'
已知可以通过Extract提取出包含${number}的成员:
Extract<Foo, `${string}.${number}` | `${string}.${number}.${string}`> // 结果:`a.${number}` | `a.${number}.c`
但不知道如何把这些模板字面量转换为对应的纯字符串字面量类型,请问这是否可行?
解决方案
可行,我们可以通过TypeScript的类型递归匹配与字符串拼接逻辑实现这个转换,核心是把模板字面量中的${number}片段替换成字符串形式的"${number}",同时保留普通字面量不变。
实现代码
// 匹配并替换单个模板中的${number}片段 type ReplaceNumberTemplate<S extends string> = S extends `${infer P}.${number}` ? `${P}.\${number}` : S extends `${infer P}.${number}.${infer Q}` ? `${P}.\${number}.${Q}` : S; // 对联合类型的每个成员应用替换逻辑 type ReplaceTemplateWithLiteral<T> = T extends string ? ReplaceNumberTemplate<T> : never;
测试验证
type Foo = 'apple' | `a.${number}` | `a.${number}.c`; type Boo = ReplaceTemplateWithLiteral<Foo>; // Boo最终类型:'apple' | 'a.${number}' | 'a.${number}.c'
如果后续需要支持其他模板变量类型(比如${string}),只需扩展ReplaceNumberTemplate的匹配分支即可。
内容的提问来源于stack exchange,提问作者Changdae Park
相关产品推荐
相关产品推荐

