TypeScript如何自动推断Record键类型同时强制值符合指定类型
需求实现方案
你提到的需求完全可以实现,这是TypeScript中非常常见的类型校验场景。
报错原因说明
你遇到的TS2344错误是因为Record的第一个泛型参数有强制约束,必须是string | number | symbol(也就是TypeScript内置的PropertyKey类型)的子类型,unknown不满足这个约束,因此写法不成立。另外如果直接给对象声明Record<string, A>类型,又会把键的类型拓宽为通用的string,丢失字面量联合类型的推断效果,也不符合你的需求。
可行解决方法
方案1:TS 4.9及以上版本使用satisfies操作符(推荐)
这是当前最简洁的解法,不需要额外封装工具代码,同时满足「保留键的字面量联合类型」和「强制所有值符合指定类型校验」两个需求:
// 假设你定义的值类型A如下 type A = { id: number; name: string }; const config = { prop1: { id: 1, name: "属性1" }, prop2: { id: 2, name: "属性2" }, prop3: { id: 3, name: "属性3" }, } satisfies Record<PropertyKey, A>; // 效果验证: // 1. 键会被自动推断为 "prop1" | "prop2" | "prop3" 联合类型 type ConfigKeys = keyof typeof config; // 2. 如果值不符合A的类型定义,TS会直接抛出校验错误
方案2:低于TS 4.9版本使用泛型辅助函数
如果你的项目TS版本较低不支持satisfies语法,可以通过封装通用泛型函数实现相同效果:
type A = { id: number; name: string }; // 定义通用工具函数,先指定值类型,再自动推断传入对象的键类型 const defineObjWithValueType = <Value,>() => { return <Key extends PropertyKey>(obj: Record<Key, Value>) => obj; }; // 先传入值类型A生成专用构造函数 const defineAConfig = defineObjWithValueType<A>(); const config = defineAConfig({ prop1: { id: 1, name: "属性1" }, prop2: { id: 2, name: "属性2" }, prop3: { id: 3, name: "属性3" }, }); // 效果和satisfies完全一致
内容的提问来源于stack exchange,提问作者Peeyush Kushwaha
相关产品推荐
相关产品推荐

