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

如何为支持柯里化的map函数添加正确的TypeScript类型?

你当前的实现问题在于使用了any和宽泛的Function类型,丢失了输入类型和输出类型的映射关系。练习题的测试不仅要求没有编译报错,还要求TS能正确推导不同调用方式下的返回值类型,所以才会不通过。

测试用例逻辑说明

你看到的const mapResult1 = map()(String)()([1, 2, 3]);是这个函数的柯里化占位调用特性:

  • 任意一层调用时如果不传参数,就直接返回当前函数本身,允许延迟传入参数
  • 第一次传入mapper函数后,会返回等待输入数组的子函数
  • 最后传入输入数组时,才会执行映射逻辑返回结果

正确实现思路

因为这个函数根据传入参数的数量、种类返回完全不同的类型,需要用TS的函数重载来描述不同调用场景的类型约束,而不是用单个泛型签名。

首先定义子函数的类型,描述子函数的两种调用规则:

// 子函数类型:不传参返回自身,传T类型数组返回U类型数组
type PartialMap<T, U> = {
  (): PartialMap<T, U>
  (input: T[]): U[]
}

然后给map函数写三个重载,对应三种调用场景:

// 重载1:无参调用,返回map函数本身
export function map(): typeof map

// 重载2:只传mapper函数,返回等待输入数组的子函数
export function map<T, U>(mapper: (item: T) => U): PartialMap<T, U>

// 重载3:同时传mapper和输入数组,直接返回映射后的数组
export function map<T, U>(mapper: (item: T) => U, input: T[]): U[]

最后写函数实现即可,运行逻辑和原有代码完全一致,实现签名只要兼容所有重载就行:

export function map(mapper?: unknown, input?: unknown) {
  if (arguments.length === 0) {
    return map;
  }
  if (arguments.length === 1) {
    return function subFunction(subInput?: unknown) {
      if (arguments.length === 0) {
        return subFunction;
      }
      return (subInput as Array<unknown>).map(mapper as (item: unknown) => unknown);
    };
  }
  return (input as Array<unknown>).map(mapper as (item: unknown) => unknown);
}

完成后TS就能正确推导所有调用场景的类型,比如上述测试用例的返回值会被自动推导为string[],符合测试要求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 13:45:06