如何为支持柯里化的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
相关产品推荐
相关产品推荐

