TypeScript中柯里化函数无法实现重载的问题求助
柯里化场景下TypeScript函数重载类型匹配问题解决
问题场景
需要实现一个柯里化函数,根据传入的精确字符串参数返回对应类型:传入'left'返回boolean,传入'right'返回number。非柯里化时类型推断正常,但柯里化后重载功能失效。
正常工作的非柯里化代码
type Simple = { (side: 'left'): boolean; (side: 'right'): number; }; const simple: Simple = (side: 'left' | 'right') => (side === 'left' ? random([true]) : random([1])) as boolean & number; const simpleLeft = simple('left'); // boolean ✔️ const simpleRight = simple('right'); // number ✔️
柯里化后失效的代码
type Hard = { (): (side: 'left') => boolean; (): (side: 'right') => number; }; const hard: Hard = () => (side: 'left' | 'right') => (side === 'left' ? random([true]) : random([1])) as boolean & number; const hardLeft = hard()('left'); // boolean ✔️ const hardRight = hard()('right'); // boolean ❌
辅助函数random定义
const random = <T>(array: T[]) => array[Math.floor(Math.random() * array.length)] as T;
解决方案
问题根源在于原Hard类型的重载定义错误:给hard()本身设置了两个无参数的重载,TypeScript会优先匹配第一个重载,导致返回的函数被固定为(side: 'left') => boolean,无法正确推断'right'参数对应的返回类型。
正确的做法是让hard()返回一个自带重载逻辑的函数类型,而非给hard()本身做重载。
方案一:拆分类型定义
// 定义柯里化后返回的函数类型(带重载) type CurriedSideFn = { (side: 'left'): boolean; (side: 'right'): number; }; // 柯里化函数的类型 type Hard = () => CurriedSideFn; const hard: Hard = () => { const fn = (side: 'left' | 'right') => side === 'left' ? random([true]) : random([1]); return fn as CurriedSideFn; }; const hardLeft = hard()('left'); // boolean ✔️ const hardRight = hard()('right'); // number ✔️
方案二:合并类型定义(简洁版)
type Hard = () => { (side: 'left'): boolean; (side: 'right'): number; }; const hard: Hard = () => (side: 'left' | 'right') => side === 'left' ? random([true]) : random([1]) as boolean | number; const hardLeft = hard()('left'); // boolean ✔️ const hardRight = hard()('right'); // number ✔️
原理说明
修改后的类型定义中,hard()返回的是一个带有重载的函数,TypeScript会根据后续传入的side参数值,匹配对应的重载规则,从而正确推断返回类型。
内容的提问来源于stack exchange,提问作者Pleklo
相关产品推荐
相关产品推荐

