如何在TypeScript中对Record定义的对象实现键类型推断?
TypeScript 对象键类型推断方案问题
现有方案对比
方案A(键推断失效)
// A export const config: Record<string, number> = { a: 1, b: 2, } as const export const test = (configKey: keyof typeof config) => { console.log(configKey) } test('') // 无法推断具体允许的键
方案B(键推断正常,但不符合需求)
// B type A = 'a' | 'b' export const config: Record<A, number> = { a: 1, b: 2, } as const export const test = (configKey: keyof typeof config) => { console.log(configKey) } test('') // 可正常推断允许的键为'a'/'b'
需求与问题
我的对象值类型实际场景中比示例的number更复杂,目前面临的矛盾是:
- 方案A无法让接收对象键的函数实现具体键类型推断;
- 方案B虽能正常推断,但不符合我的核心需求:
- 编写对象内容时,能获得
Record类型的提示支持; - 修改对象内容时,无需修改其他代码(键集合可动态更新)。
- 编写对象内容时,能获得
想请教如何在符合方案A核心需求的前提下,实现对象键的类型推断?
解决方案
可以通过泛型辅助函数来定义对象,既约束值的类型符合Record的要求,又保留键的字面量类型,从而同时满足提示支持和自动推断的需求:
// 泛型辅助函数,约束值类型为指定类型(示例为number,实际可替换为复杂类型) const createConfig = <K extends string>(config: Record<K, number>): typeof config => config; // 创建config对象,自动推断键的字面量类型,同时值会被约束为number export const config = createConfig({ a: 1, b: 2, } as const); // 此时keyof typeof config为具体的键联合类型'a'|'b' export const test = (configKey: keyof typeof config) => { console.log(configKey); }; test('a'); // 正常提示允许的键,传入非'a'/'b'会报错
方案优势
- 编写时的提示支持:
createConfig的参数被约束为Record<K, number>,输入键值对时TypeScript会自动提示值必须符合指定类型(替换为复杂类型同样生效); - 修改无需额外代码:直接修改
createConfig的参数对象(比如新增c:3),TypeScript会自动更新K的类型为新的键集合,test函数的参数类型也会同步更新,无需手动修改其他类型定义; - 键类型正常推断:最终
config的类型会保留键的字面量类型,keyof typeof config即为具体的键联合类型,实现函数参数的精准推断。
内容的提问来源于stack exchange,提问作者nyamDal
相关产品推荐
相关产品推荐

