You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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 } }确保了:
    1. 对象的每个值都是FooValue的实例;
    2. 每个键K对应的值的mainKey属性必须严格等于K;
  • 由于没有用宽泛的unknown约束类型,TypeScript可以完整推导每个first和second属性的具体类型。

内容的提问来源于stack exchange,提问作者Anubhav Gupta

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 03:20:19