TypeScript中从已定义对象提取键的问题
TypeScript中从已定义对象提取具体键的解决方案
问题场景:当你定义了带字符串索引签名的类型A,并将一个字面量对象赋值给标注为A的常量后,尝试提取键时得到的是string | number,而非预期的具体键名'myKey'。
问题原因
当你给变量显式标注类型A时,TypeScript会优先使用这个标注类型,而非对象字面量的推断类型。keyof A的结果是string | number(JavaScript中对象的数字键会被转换为字符串,TypeScript对字符串索引类型的键定义包含这两种类型),所以即使你用了as const,也无法改变变量的类型为A的事实。
解决方案
方案1:使用satisfies关键字(TypeScript 4.9+)
satisfies可以检查对象是否符合指定类型,但不会覆盖TypeScript对对象字面量的类型推断,既能保证结构合规,又能保留具体键名:
type A = { [key: string]: 123, } const aTyped = { myKey: 123, } as const satisfies A; type ExtractKeys<T> = keyof T; type Keys = ExtractKeys<typeof aTyped>; // Keys = 'myKey'
方案2:分离字面量类型与约束类型
先定义不带类型标注的常量,保留字面量类型,再将其赋值给标注为A的变量:
type A = { [key: string]: 123, } // 保留字面量类型的原始常量 const aLiteral = { myKey: 123, } as const; // 标注类型A,不影响原始常量的类型 const aTyped: A = aLiteral; type Keys = keyof typeof aLiteral; // Keys = 'myKey'
方案3:用泛型函数捕获具体类型
通过泛型函数创建对象,既约束对象符合A的结构,又能捕获具体的字面量类型:
type A = { [key: string]: 123, } function createA<T extends A>(obj: T) { return obj; } const aTyped = createA({ myKey: 123, } as const); type ExtractKeys<T> = keyof T; type Keys = ExtractKeys<typeof aTyped>; // Keys = 'myKey'
内容的提问来源于stack exchange,提问作者Page not found
相关产品推荐
相关产品推荐

