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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 08:03:56