TypeScript中动态泛型值的映射类型实现问题
解决TypeScript中键与mainKey一致的类型校验及类型推导问题
问题需求
给定以下接口:
interface FooValue<A,B> { mainKey: string; first: A; second: B; }
需要创建一个对象,要求对象的每个键必须与对应值的mainKey属性值完全一致,同时希望TypeScript能正确推导每个属性的具体类型(而非unknown)。示例输入如下:
const input = { key1: {first: "text1", second: 1, mainKey: "key1"}, key2: {first: 2, second: "text2", mainKey: "key2"}, }; function acceptInput(input: /* 键与FooValue的mainKey值对应的映射类型 */){ return input; }
现有代码的问题
你尝试的代码存在两个核心问题:
- 用
FooValueObj = { [key: string]: FooValue<unknown, unknown> }约束泛型时,直接将所有值的类型宽泛化为FooValue<unknown, unknown>,导致TypeScript无法推导具体的A和B类型。 FooConfig的映射逻辑虽然尝试关联键与mainKey,但由于泛型约束的宽泛性,无法严格校验键与mainKey的一致性,也无法保留原始类型信息。
正确实现方案
通过泛型约束直接强制对象的键与对应值的mainKey相等,同时保留具体类型信息:
interface FooValue<A,B> { mainKey: string; first: A; second: B; } // 泛型约束:每个键K对应的值必须是FooValue类型,且mainKey严格等于K function acceptInput<T extends { [K in keyof T]: FooValue<any, any> & { mainKey: K } }>(input: T) { return input; } // 合法输入:键与mainKey一致,类型推导正常 const x = acceptInput({ key1: {first: "text1", second: 1, mainKey: "key1"}, key2: {first: 2, second: "text2", mainKey: "key2"}, }); x.key1.first; // TypeScript推导类型为string x.key2.first; // TypeScript推导类型为number // 非法输入:键与mainKey不一致,TypeScript会直接报错 const invalidInput = acceptInput({ key1: {first: "text1", second: 1, mainKey: "wrongKey"} // 错误:类型不匹配,mainKey必须为"key1" });
方案说明
- 泛型约束
T extends { [K in keyof T]: FooValue<any, any> & { mainKey: K } }确保了:- 对象的每个值都是
FooValue的实例; - 每个键
K对应的值的mainKey属性必须严格等于K;
- 对象的每个值都是
- 由于没有用宽泛的
unknown约束类型,TypeScript可以完整推导每个first和second属性的具体类型。
内容的提问来源于stack exchange,提问作者Anubhav Gupta
相关产品推荐
相关产品推荐

