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

TypeScript如何实现泛型函数value参数类型依赖key参数值

问题原因

当前写法无法实现类型约束的核心原因:

  • 写法typeof T[key]本身不符合TS类型语法:typeof仅能对值空间的变量做类型提取,无法直接操作泛型类型参数。
  • 仅声明泛型T时,入参key的类型会被推导为所有keyof T的联合类型,对应的value类型会被推导为T所有属性值的联合类型,TS无法根据单次调用传入的单个具体key值,收窄value的匹配类型。
修复方案

新增一个继承自keyof T的泛型参数K,专门捕获调用时传入key的具体字面量类型,再将value的类型声明为T[K]即可实现联动约束:

const fn = <T, K extends keyof T>({
  key,
  value
}: {
  key: K;
  value: T[K];
}) => {
  return undefined;
};

type Obj = {
  keyA: {
    propertyFromA: string;
  };
  keyB: {
    propertyFromB: string;
  };
};

// 错误传参会触发类型校验
fn<Obj, "keyA">({
  key: "keyA",
  value: { propertyFromB: "string" } // TS抛出类型错误,不符合{propertyFromA: string}约束
});

// 正确传参校验通过
fn<Obj, "keyA">({
  key: "keyA",
  value: { propertyFromA: "string" }
});

注意:非柯里化的写法如果只传第一个泛型参数fn<Obj>(...),TS不会自动推导第二个泛型K,会退化为之前的联合类型校验失效问题,因此要么手动传入K的具体类型,要么用柯里化写法让TS自动推导。

推导优化

如果不想每次调用都手动传入第二个泛型参数K,可以用柯里化写法提前绑定目标类型T,TS会自动根据后续传入的key值推导K的具体类型,无需手动标注:

const fn = <T>() => <K extends keyof T>({
  key,
  value
}: {
  key: K;
  value: T[K];
}) => {
  return undefined;
};

type Obj = {
  keyA: {
    propertyFromA: string;
  };
  keyB: {
    propertyFromB: string;
  };
};

// 提前绑定Obj类型
const useObjFn = fn<Obj>();

// 自动做类型联动校验
useObjFn({
  key: "keyA",
  value: { propertyFromB: "string" } // 自动抛出类型错误
});

useObjFn({
  key: "keyB",
  value: { propertyFromB: "string" } // 校验通过
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 21:45:33