TypeScript:opposite高阶函数返回值类型不兼容问题求助
TypeScript高阶函数
opposite的类型定义问题解决 问题场景
你编写的opposite高阶函数需求明确:接收返回boolean或number的函数fn,返回同类型的新函数——对boolean结果取反,对number结果返回1(原结果为0时)或0(原结果非0时)。但当前代码中两个return语句均触发TS错误:Type 'number' is not assignable to type 'ReturnType<T>' ts(2322)。
错误原因
这是TypeScript泛型控制流分析的限制导致的:
虽然你限定了T是返回boolean或number的函数,但ReturnType<T>是依赖泛型T的动态类型。TS无法在typeof result === "number"的分支里,把ReturnType<T>和具体的number类型做关联;也无法在else分支关联到boolean类型。因此即使返回值属于boolean | number,TS也不认为它匹配ReturnType<T>这个泛型类型。
解决方案
方案1:使用条件类型约束返回值
通过自定义条件类型,让TS精准推断返回函数的类型与入参函数的返回类型一致:
// 定义入参函数的类型范围 type BooleanOrNumberFn = (...args: any[]) => boolean | number; // 条件类型:根据入参函数的返回类型,确定新函数的返回类型 type OppositeReturn<T extends BooleanOrNumberFn> = T extends (...args: any[]) => boolean ? boolean : number; const opposite = <T extends BooleanOrNumberFn>(fn: T) => { return (...args: Parameters<T>): OppositeReturn<T> => { const result = fn(...args); if (typeof result === "number") { // 类型断言告诉TS返回值符合条件类型结果 return (result === 0 ? 1 : 0) as OppositeReturn<T>; } else { return (!result) as OppositeReturn<T>; } }; };
方案2:使用函数重载(更直观)
函数重载可以直接为不同类型的入参函数定义对应的返回函数类型,TS能自动匹配:
// 重载签名:分别定义两种入参对应的返回类型 function opposite(fn: (...args: any[]) => boolean): (...args: any[]) => boolean; function opposite(fn: (...args: any[]) => number): (...args: any[]) => number; // 函数实现 function opposite(fn: (...args: any[]) => boolean | number) { return (...args: any[]) => { const result = fn(...args); if (typeof result === "number") { return result === 0 ? 1 : 0; } else { return !result; } }; }
验证示例
两种方案都能满足你的使用需求,比如数组过滤场景:
const nums = [1, 2, 3, 4]; const isEven = (n: number) => n % 2 === 0; // 原过滤逻辑 console.log(nums.filter(isEven)); // 输出: [2, 4] // 使用opposite反转过滤逻辑 console.log(nums.filter(opposite(isEven))); // 输出: [1, 3]
内容的提问来源于stack exchange,提问作者Federico Kereki
相关产品推荐
相关产品推荐

