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

TypeScript如何将n元组getter函数类型转为返回值n元组类型?

完美解决:用TypeScript映射类型实现元组返回值推导

嘿,这个需求太常见了!你完全不用写一堆重复的重载,TypeScript的映射类型结合条件类型推断就能优雅解决这个问题,而且支持任意长度的函数数组。

最终实现代码

// 定义ValueTupleOf类型:提取函数元组中每个函数的返回值组成新元组
type ValueTupleOf<T extends readonly (() => any)[]> = {
  [K in keyof T]: T[K] extends () => infer R ? R : never;
};

// 你的getValues函数,现在能自动推导精确的元组类型
function getValues<A extends (() => any)[]>(getters: A): ValueTupleOf<A> {
  // 这里需要类型断言,因为Array.map默认返回数组而非元组
  return getters.map(getter => getter()) as ValueTupleOf<A>;
}

为什么这能工作?

让我拆解一下关键部分:

  1. 元组约束:T extends readonly (() => any)[]确保输入是一个由函数组成的元组(加上readonly是为了兼容只读元组场景,去掉也不影响核心功能)。
  2. 映射元组:[K in keyof T]是对元组的每个索引位置进行遍历——TypeScript会把元组的数字索引当作key,所以映射后依然会保留元组的结构(而不是变成普通数组)。
  3. 提取返回值:T[K] extends () => infer R ? R : never用条件类型推断,把每个位置的函数类型拆解,提取出它的返回值类型R。

测试验证

来试试实际用例,类型推导完全精确:

const result = getValues([
  () => "Hello TypeScript",
  () => 2024,
  () => { name: "Natasha" }
]);

// result的类型会被自动推断为:
// [string, number, { name: string }]

为什么不用重载?

你原来的重载方案虽然能工作,但有明显缺点:

  • 扩展性极差,函数数组长度超过3、4个就得继续写新的重载,非常繁琐。
  • TypeScript对重载的类型推断有时候会出现边界情况(比如传入动态生成的数组时,重载可能匹配失败)。
  • 映射类型是TypeScript类型系统原生支持的方案,代码更简洁、更易维护。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.12 04:40:59