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

TypeScript如何创建可处理不同参数类型的泛型函数

解决TypeScript泛型函数中参数类型关联问题

问题场景

你尝试创建可接收不同参数的泛型函数,但TypeScript无法识别type与value的对应类型,报错:

Argument of type 'string | number' is not assignable to parameter of type 'never'.
  Type 'string' is not assignable to type 'never'. (2345)

原示例代码:

const typeToFn = {
  text: (value: string) => value,
  integer: (value: number) => value,
};

type Type = keyof typeof typeToFn;

type Value<TType extends Type> = Parameters<(typeof typeToFn)[TType]>[0]

function callFn<TType extends Type>(type: TType, value: Value<TType>) {
  const fn = typeToFn[type]

  return fn(value)
}

原因分析

原代码中,typeToFn[type]的类型被推断为联合类型((value: string) => string) | ((value: number) => number),而泛型TType对应的value类型是Value<TType>。TypeScript无法在泛型上下文里确定fn的具体类型与value类型严格匹配,因此会将参数类型的交集计算为string & number(即never),触发类型错误。

解决方案

方案1:使用联合元组约束参数(推荐)

通过生成包含所有合法参数组合的联合元组类型,让TypeScript直接识别每个type对应的value类型:

const typeToFn = {
  text: (value: string) => value,
  integer: (value: number) => value,
  // 可扩展更多类型
  boolean: (value: boolean) => value,
};

type TypeToFn = typeof typeToFn;
// 生成[type, value]的联合元组类型,覆盖所有合法参数组合
type CallFnArgs = {
  [K in keyof TypeToFn]: [type: K, value: Parameters<TypeToFn[K]>[0]]
}[keyof TypeToFn];

function callFn(...args: CallFnArgs) {
  const [type, value] = args;
  const fn = typeToFn[type];
  return fn(value);
}

// 测试用例
callFn('text', 'hello'); // 类型正确
callFn('integer', 123); // 类型正确
callFn('boolean', true); // 类型正确
callFn('text', 123); // 类型错误(符合预期)

这种方式无需额外断言,TypeScript能自动推断参数的对应关系,且扩展新类型时只需修改typeToFn对象即可,维护性更好。

方案2:使用类型断言(快速修复)

如果不想重构函数参数结构,可以通过类型断言明确告知TypeScript当前fn的类型:

const typeToFn = {
  text: (value: string) => value,
  integer: (value: number) => value,
};

type Type = keyof typeof typeToFn;
type Value<TType extends Type> = Parameters<(typeof typeToFn)[TType]>[0];

function callFn<TType extends Type>(type: TType, value: Value<TType>) {
  // 断言fn为与TType匹配的函数类型
  const fn = typeToFn[type] as (value: Value<TType>) => ReturnType<(typeof typeToFn)[TType]>;
  return fn(value);
}

注意:这种方式需要手动维护断言类型,若后续typeToFn新增或修改类型,需同步调整断言,适合简单场景临时修复。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 17:55:17