TypeScript:不修改对象类型,如何用其具体键定义限定类型?
解决方法
问题根源在于你给obj显式标注了索引签名类型{[key: string]: string},TypeScript会直接采用这个标注类型,而非推断对象的字面量键类型,所以keyof typeof obj得到的是string而非具体的"foo"或"bar"。
以下是两种符合要求的解决方式:
方式一:使用satisfies运算符(TypeScript 4.9+)
用satisfies替换显式类型标注,既能保证obj符合{[key: string]: string}类型约束,又能让TypeScript保留对象的字面量键信息:
const obj = {foo: 'x', bar: 'y'} satisfies {[key: string]: string}; type ObjType = keyof typeof obj; // 类型为 "foo" | "bar"
方式二:保留原类型标注的前提下通过中间常量捕获字面量
如果必须保留obj原有的类型定义(即const obj: {[key: string]: string}),可以先定义一个带as const断言的中间常量,再赋值给obj,最后从中间常量的类型中提取键:
const objLiteral = {foo: 'x', bar: 'y'} as const; const obj: {[key: string]: string} = objLiteral; type ObjType = keyof typeof objLiteral; // 类型为 "foo" | "bar"
as const会强制TypeScript将对象的键和值推断为字面量类型,因此typeof objLiteral的类型是包含具体键的字面量对象类型,keyof操作后就能得到你需要的"foo" | "bar",同时obj的类型完全符合原定义,没有被修改。
内容的提问来源于stack exchange,提问作者Chubby Cows
相关产品推荐
相关产品推荐

