如何用TypeScript确保对象值是其键推导类型的键?
解决方案:根据对象key映射对应类型的键
当前MyType的问题在于,keyof T中的T是Dog | Cat的联合类型,而联合类型的keyof只会返回所有成员的公共属性(也就是id),因此才会出现只能赋值id的错误。要实现每个key对应专属类型的键,我们需要先建立id到具体动物类型的映射,再基于这个映射生成目标类型。
修正后的代码实现
// GIVEN type Animal<T extends string> = { id: T, } type Dog = Animal<"animal.dog"> & { foo: string } type Cat = Animal<"animal.cat"> & { bar: string } // 新增:建立id到对应动物类型的映射 type AnimalMap = { "animal.dog": Dog; "animal.cat": Cat; }; // 基于映射生成目标类型:每个key对应其映射类型的键 type MyType = { [K in keyof AnimalMap]: keyof AnimalMap[K] }; // EXPECT TO BE OK:符合要求,无报错 const obj: MyType = { "animal.dog": "foo", // 属于Dog的键(id/foo) "animal.cat": "bar" // 属于Cat的键(id/bar) } // EXPECT TO FAIL:类型不匹配,触发错误 const fail: MyType = { "animal.dog": "bar", // bar不是Dog的键 "animal.cat": "foo" // foo不是Cat的键 }
关键说明
AnimalMap:明确每个id字符串对应的具体动物类型,让TypeScript能精准关联key和对应的类型。MyType:通过keyof AnimalMap遍历所有id,每个属性值的类型设置为对应动物类型的键(keyof AnimalMap[K]),确保每个key的value只能是该类型允许的键名。
测试后,正确的obj会通过类型检查,错误的fail会触发如下报错:
Type '"bar"' is not assignable to type 'keyof Dog'Type '"foo"' is not assignable to type 'keyof Cat'
完全符合需求。
内容的提问来源于stack exchange,提问作者Maxime Lechevallier
相关产品推荐
相关产品推荐

