TypeScript泛型函数convert处理数组方法时类型推导错误如何修正
问题原因
你遇到的类型推导问题根源在于原有实现的泛型参数会在调用convert时就被固定:你传入的[].shift、[].map是any[]类型的原型方法,泛型参数T在convert调用阶段就被推导为any[]对应的方法类型,后续调用返回函数时,TS不会再根据你传入的实际this参数(比如string[])重新计算泛型,就出现了返回值为undefined、参数类型为never的错误。
解决方案
我们需要把泛型计算逻辑延迟到返回函数被调用时执行,每次调用都根据实际传入的this参数类型实时计算参数和返回值类型,修改后的代码如下:
export function convert<F extends (this: any, ...args: any[]) => any>(func: F) { return <This>( _this: This, ...args: F extends (this: This, ...args: infer Args) => any ? Args : never ): F extends (this: This, ...args: any) => infer Return ? Return : never => { return func.apply(_this, args); }; }
你也可以保留原来的函数实现逻辑,只调整类型定义即可:
export function convert<F extends (this: any, ...args: any[]) => any>(func: F) { return Function.call.bind( Function.bind, Function.call )(func) as <This>( _this: This, ...args: F extends (this: This, ...args: infer Args) => any ? Args : never ) => F extends (this: This, ...args: any) => infer Return ? Return : never; }
效果验证
修改后再运行你的测试用例,类型推导就会符合预期:
const arrayShift = convert([].shift); // 推导结果:const shifted: string | undefined const shifted = arrayShift(["1"]); const arrayMap = convert([].map); // 推导结果:(parameter) e: string arrayMap(["1"], (e) => { return parseInt(e, 10); });
注意:
shift方法本身在数组为空时会返回undefined,所以推导结果为string | undefined是符合运行逻辑的,如果你确定数组不为空,可以使用非空断言!得到纯string类型。
内容的提问来源于stack exchange,提问作者Ezio 1212
相关产品推荐
相关产品推荐

