TypeScript如何限制对象类型的同时获取对象原始字面量键类型
问题核心原因
你直接给config标注IConfig类型时,TypeScript会直接将变量类型向上拓宽为声明的IConfig类型,而IConfig的索引签名是[key: string],所以keyof typeof config最终得到的是索引签名的类型string | number,丢失了对象实际的字面量键信息。
解法1:使用 TS 4.9+ 支持的 satisfies 运算符(推荐)
satisfies是TypeScript 4.9版本专门推出的语法,作用就是校验值是否符合指定类型,同时不丢失值本身的原始类型推导,刚好匹配你的需求。
代码示例:
type IConfig = { [key: string]: { type: string; age: number; }; } // 用satisfies替代直接的类型注解 const config = { a: { type: '123', age: 123, } } satisfies IConfig; // 此时可以正确拿到字面量键类型 type keys = keyof typeof config; // 类型为 'a'
如果你的config结构不符合IConfig的要求(比如age传了字符串、少了属性),TypeScript会正常抛出类型错误,满足你限制类型的需求。
解法2:使用泛型辅助函数(兼容低版本TS)
如果你的项目TypeScript版本低于4.9,没法用satisfies,可以写一个简单的泛型工具函数实现同等效果:
type IConfig = { [key: string]: { type: string; age: number; }; } // 定义泛型工具函数,既约束传入的参数符合IConfig,又保留参数本身的类型推导 const defineConfig = <T extends IConfig>(config: T) => config; const config = defineConfig({ a: { type: '123', age: 123, } }); type keys = keyof typeof config; // 类型为 'a'
同样的,如果传入的对象不符合IConfig的结构,调用defineConfig时就会抛出类型错误。
内容的提问来源于stack exchange,提问作者87639243qqcom
相关产品推荐
相关产品推荐

