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

如何推导参数为带可选参数函数的TypeScript重载函数类型

问题解决办法

你遇到的报错是因为 TypeScript 不会自动合并重载签名的参数类型推导到实现函数上,需要你手动给实现的参数标注联合类型,具体方案如下:

方案1:直接标注参数联合类型

给实现函数的arg参数显式标注两种入参的联合类型,同时类型收窄逻辑可以正常工作:

interface OverloadedFn<TArgs>  {
    (args: TArgs): void;
    (setter: (prev: TArgs) => TArgs): void;
}

const overloadedFn: OverloadedFn<{ arg1: number }> = (arg: { arg1: number } | ((prev: { arg1: number }) => { arg1: number })) => {
    if (typeof arg === 'function') {
      // 此时arg自动收窄为函数类型,可直接调用
      const newState = arg({ arg1: 0 })
    } else {
      // 此时arg自动收窄为状态值类型,可直接读取属性
      console.log(arg.arg1)
    }
}

方案2:从重载类型提取参数类型(更通用)

如果不想重复写类型,可以直接从定义的重载接口中提取参数类型,避免重复声明:

interface OverloadedFn<TArgs>  {
    (args: TArgs): void;
    (setter: (prev: TArgs) => TArgs): void;
}
// 提取重载的入参类型
type OverloadedFnParam<T> = Parameters<OverloadedFn<T>>[0]

const overloadedFn: OverloadedFn<{ arg1: number }> = (arg: OverloadedFnParam<{ arg1: number }>) => {
    if (typeof arg === 'function') {
      // 逻辑同上
    } else {
      // 逻辑同上
    }
}

方案3:直接使用函数重载写法(TS 4.7+ 推荐)

如果你的项目TS版本高于4.7,直接用函数声明式重载的写法更简洁,TS可以自动识别:

// 重载签名
function useStateSetter<T>(args: T): void
function useStateSetter<T>(setter: (prev: T) => T): void
// 实现签名
function useStateSetter<T>(arg: T | ((prev: T) => T)) {
  if (typeof arg === 'function') {
    // 处理setter逻辑
  } else {
    // 处理直接传值逻辑
  }
}

// 调用示例,类型自动推导
useStateSetter({ arg1: 1 })
useStateSetter((prev) => ({ arg1: prev.arg1 + 1 }))

内容的提问来源于stack exchange,提问作者RocketMeister

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 23:09:02