如何从非字面量数组(Object.keys与Array.map)推导联合类型?
如何从非字面量数组推导联合类型?
你当前的代码里,Object.keys()在TypeScript中默认返回string[],后续map生成的数组类型也会是string[],所以最终得到的类型是宽泛的string,而非期望的字面量联合类型。要实现需求,得从类型层面处理字符串前缀,同时让TypeScript保留对象键的字面量信息,具体步骤如下:
- 给
tokens添加as const断言,强制TypeScript将对象的键推断为字面量类型(而非string):
const tokens = { "--prefix-apple": "apple", "--prefix-orange": "orange" } as const;
- 通过TypeScript的模板字面量类型提取去掉前缀后的联合类型:
// 获取tokens的所有键类型 type TokenKey = keyof typeof tokens; // 匹配前缀并提取核心部分 type TokenNamesWithoutPrefix = TokenKey extends `--prefix-${infer T}` ? T : never;
此时TokenNamesWithoutPrefix就是你想要的"apple" | "orange"。
- 如果需要运行时的
tokenNames数组也对应这个类型,给Object.keys()添加类型断言,确保它返回字面量键数组,再将map结果断言为目标类型数组:
const tokenNames = (Object.keys(tokens) as TokenKey[]).map(token => token.replace("--prefix-", "") ) as TokenNamesWithoutPrefix[];
现在typeof tokenNames[number]会正确推断为"apple" | "orange"。
本质原因是:运行时的map属于JavaScript逻辑,TypeScript无法追踪每个元素的具体字面量值,只能推断为string;而通过类型层面的模板字面量匹配,能直接从对象的键类型中提取出精准的联合类型。
内容的提问来源于stack exchange,提问作者Jake Metz
相关产品推荐
相关产品推荐

