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

TypeScript中如何定义接收任意数量不同返回类型Supplier的函数并推导返回元组类型

TypeScript中如何定义接收任意数量不同返回类型Supplier的函数并推导返回元组类型

当然可以做到!你只需要借助TypeScript的泛型元组和映射类型,就能让编译器精准推导出返回值的元组类型,完全适配任意数量的不同Supplier参数。

先回顾你的Supplier类型定义:

type Supplier<T> = () => T;

接下来我们这样定义函数f:

function f<T extends Supplier<any>[]>(...args: T): { [K in keyof T]: ReturnType<T[K]> } {
  // 执行每个Supplier并返回结果,这里用as any是因为map默认返回数组而非元组,我们已经通过泛型约束好了类型,所以是安全的
  return args.map(supplier => supplier()) as any;
}

我来拆解一下这段代码的逻辑:

  • 泛型T extends Supplier<any>[]:用来捕获你传入的所有Supplier参数组成的元组类型(注意这里不是普通数组,TypeScript会自动把可变参数推断为元组)
  • 返回类型{ [K in keyof T]: ReturnType<T[K]> }:通过映射类型遍历元组的每个索引,用内置的ReturnType工具类型提取每个Supplier的返回值类型,最终组合成和参数顺序完全对应的元组类型
  • 函数体里的args.map就是简单执行每个Supplier函数,收集结果。之所以用as any断言,是因为TypeScript的Array.map方法默认返回普通数组,而我们需要的是严格的元组类型,不过因为泛型已经约束了返回类型,这个断言不会有类型安全问题

现在试试你给出的调用场景:

const values = f(() => 3, () => "text", () => true);
// 此时values的类型会被自动推导为 [number, string, boolean]

如果你想让泛型约束更严谨,也可以把Supplier<any>换成Supplier<unknown>,效果是一样的,只是语义上更强调“未知的返回类型”。

另外,如果你不想用ReturnType,也可以手动用条件类型提取返回值:

function f<T extends Supplier<any>[]>(...args: T): { [K in keyof T]: T[K] extends Supplier<infer U> ? U : never } {
  return args.map(supplier => supplier()) as any;
}

这段代码和前面的版本功能完全一致,只是把ReturnType换成了手动的infer推导,本质是一样的。

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.08 10:43:04