如何在TypeScript中将处理得到的数组值推导为字面量联合类型
问题原因
- TypeScript 的类型系统是编译期静态执行的,
map、Set转换都是运行时动态操作,TS 无法追踪这类操作的字面量类型 - const 断言只能对字面量表达式生效,对已经推导为通用
string[]类型的变量使用 const 断言不会生效
解决方案
我们可以直接在类型层面通过模板字面量处理键名,完全在编译期得到目标联合类型,运行时需要数组时再做断言即可:
- 首先给
color对象添加as const固定所有键的字面量类型 - 编写工具类型递归去除键名中的数字,利用联合类型天然去重的特性得到最终类型
完整代码示例
// 给color对象加as const,固定所有键的字面量类型 const color = { blue100: '#...', blue500: '#...', red100: '#...', red500: '#...', yellow100: '#...', yellow500: '#...', } as const; // 工具类型:递归去除字符串中的数字部分 type RemoveNum<T extends string> = T extends `${infer Prefix}${number}${infer Suffix}` ? RemoveNum<`${Prefix}${Suffix}`> : T; // 直接在类型层面处理,自动去重得到目标联合类型 export type ColorNameType = RemoveNum<keyof typeof color>; // 此时ColorNameType自动为 'blue' | 'red' | 'yellow',符合预期 // 如果运行时需要对应的数组,直接断言类型即可 const colorNames = [...new Set(Object.keys(color).map(x => x.replace(/[0-9]/g, '')))] as ColorNameType[];
后续如果要新增颜色,只需要修改 color 对象的定义,ColorNameType 会自动更新,无需手动维护类型。
内容的提问来源于stack exchange,提问作者Horai Nuri
相关产品推荐
相关产品推荐

