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

如何在TypeScript中实现元组的泛型函数分发映射?

实现保留元组长度与类型窄化的map函数

核心解决方案

通过泛型映射类型结合函数参数的类型推断,可以实现严格保留元组长度和窄化类型的map函数。以下是两种可行实现:

方案1:通用映射类型方案

// 定义元组映射类型,针对每个元素应用函数的返回类型
type MapTuple<T extends readonly any[], F> = {
  [K in keyof T]: F extends (arg: T[K]) => infer R ? R : never;
};

function mapTuple<T extends readonly any[], F extends (arg: any) => any>(
  tuple: T,
  func: F
): MapTuple<T, F> {
  // 手动断言类型,因为Array.map默认返回数组而非元组
  return tuple.map(func as any) as MapTuple<T, F>;
}

// 测试示例
const input = ["a", "b", "c"] as const;
const result = mapTuple(input, (e) => `__${e}` as const);
// result类型为:["__a", "__b", "__c"]

方案2:针对特定映射规则的简化方案

如果已知映射规则(比如固定前缀拼接),可以直接构造字面量类型映射,更直观:

function mapTuple<T extends readonly string[]>(
  tuple: T,
  func: <U extends T[number]>(arg: U) => `__${U}`
): { [K in keyof T]: `__${T[K]}` } {
  return tuple.map(func as any) as any;
}

// 测试示例
const input = ["a", "b", "c"] as const;
const result = mapTuple(input, e => `__${e}` as const);
// result类型为:["__a", "__b", "__c"]

关键原理说明

  1. 避免类型拓宽:必须在映射函数的返回值后添加as const,强制TS保留字符串字面量类型,否则__${e}会被自动拓宽为string类型。
  2. 映射类型遍历元组:通过[K in keyof T]遍历元组的每个索引,确保输出元组与输入元组长度完全一致。
  3. 泛型函数的类型匹配:方案1中利用F extends (arg: T[K]) => infer R,让TS针对每个元组元素的具体类型,推断函数对应的返回类型,解决了直接实例化泛型函数导致的类型丢失问题。

注意事项

  • 由于TS内置的Array.map返回值是数组类型而非元组,因此需要通过类型断言将结果转换为我们定义的元组类型。
  • 若映射函数的逻辑更复杂,只需确保函数的泛型参数能正确关联输入元素的字面量类型,即可保留窄化后的输出类型。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 04:00:52