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

如何从联合类型中推断函数参数?TypeScript类型定义问题

解决TypeScript联合函数类型的对应元组类型问题

问题分析

你定义了两个函数的联合类型Functions,想要创建元组类型确保第一个元素是函数,第二个元素是该函数对应的name参数允许值,但原写法存在两个核心问题:

  • 类型约束缺失导致报错:Parameters<T>[2]要求T必须是函数类型,但原泛型未添加约束,引发Type 'T' does not satisfy the constraint '(...args: any) => any'错误。
  • 类型匹配不严格:即使忽略报错,Parameters<Functions>[2]会得到所有函数name参数的联合值,无法限制元组中函数与name参数的一一对应,比如会允许[Function1, "foo"]这种不合法的组合。

解决方案

使用分布式条件类型,针对联合类型中的每个函数成员,单独提取其name参数类型,生成对应的匹配元组:

function Function1(arg0: string, arg1: any[], name: "hello" | "bye") {
  return name;
}

function Function2(arg0: string, arg1: any[], name: "foo" | "bar") {
  return name;
}

type Functions = typeof Function1 | typeof Function2;

// 定义单个函数对应的元组类型:函数 + 自身的name参数类型
type FunctionNameTuple<T extends (...args: any) => any> = 
  T extends (...args: [string, any[], infer Name]) => any 
    ? [T, Name] 
    : never;

// 生成Functions联合类型对应的所有合法元组的联合
type FooBar = FunctionNameTuple<Functions>;

验证效果

现在FooBar是两个合法元组类型的联合:[typeof Function1, "hello" | "bye"] | [typeof Function2, "foo" | "bar"],能严格约束函数与name参数的匹配:

// 合法示例
const valid1: FooBar = [Function1, "hello"];
const valid2: FooBar = [Function1, "bye"];
const valid3: FooBar = [Function2, "foo"];
const valid4: FooBar = [Function2, "bar"];

// 非法示例(会触发类型错误)
const invalid: FooBar = [Function1, "foo"]; // 错误:"foo"不属于Function1的name参数类型

泛型版本(可选)

如果需要支持传入单个函数类型生成对应元组,可以将FooBar定义为泛型:

type FooBar<T extends (...args: any) => any = Functions> = 
  T extends (...args: [string, any[], infer Name]) => any 
    ? [T, Name] 
    : never;

// 使用示例
type Function1Tuple = FooBar<typeof Function1>; // [typeof Function1, "hello" | "bye"]
type DefaultTuple = FooBar; // 等价于之前的FooBar类型

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 06:48:25