TypeScript中动态访问自定义类型属性时如何定义对应值的类型
TypeScript 动态属性值类型约束实现方案
核心方案是使用泛型建立属性名和属性值类型的关联,替换原有any类型即可实现自动类型校验,修改后代码如下:
interface MyType { prop1: string; prop2: number; } const testValue = <K extends keyof MyType>( obj: MyType, property: K, value: MyType[K], ) => { if (obj[property] === value) { console.log("do something"); } } testValue({prop1: "a", prop2: 1}, "prop1", "okay"); // 类型校验通过 testValue({prop1: "a", prop2: 1}, "prop2", "oops"); // 抛出类型错误:类型'string'不能赋值给类型'number'
实现原理
- 原写法中
property的类型是keyof MyType,即"prop1" | "prop2"的联合类型,TypeScript无法确定调用时传入的是哪一个具体属性,因此无法推导对应值的类型,只能手动标注为any绕过校验。 - 新增泛型参数
<K extends keyof MyType>后,TypeScript会在函数调用时根据传入的property参数自动推断K的具体字面量类型:传入"prop1"时K为"prop1",此时MyType[K]对应string类型;传入"prop2"时K为"prop2",此时MyType[K]对应number类型,自动完成value的类型约束。
更高通用性的写法
如果需要这个函数适配任意自定义类型,而不是仅支持MyType,可以把对象本身也设为泛型参数,实现全场景复用:
const testValue = <T, K extends keyof T>( obj: T, property: K, value: T[K], ) => { if (obj[property] === value) { console.log("do something"); } }
这个版本的函数不需要针对每个自定义类型做修改,传入任意对象和对应合法属性名时,都会自动校验value的类型是否匹配。
内容的提问来源于stack exchange,提问作者DwightFromTheOffice
相关产品推荐
相关产品推荐

