如何从联合类型中推断函数参数?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
相关产品推荐
相关产品推荐

