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

如何修改TypeScript函数所有重载的返回类型为void?

解决TypeScript重载函数返回类型统一改为void的问题

问题场景

现有如下重载函数fooBar:

function fooBar(param1: string, param2: number): number;
function fooBar(param1: boolean): number;
function fooBar(boolOrString: boolean | string, param2?: number): number {
  if (typeof boolOrString === 'string') {
    return boolOrString.length + param2!;
  }
  return boolOrString ? 100 : -100;
}

需求是创建一个类型工具,将该函数所有重载的返回类型改为void,同时保留原有的重载参数结构。用户尝试了以下VoidFn类型:

type VoidFn<F> = F extends ((...args: infer Args) => any) | never
   ? (...args: Args) => void
   : F extends infer F1 | infer F2
   ? VoidFn<F1> | VoidFn<F2>
   : never;

但实际使用时,该类型仅修改了最后一个重载的返回类型:

type FV = VoidFn<typeof fooBar>
// 仅得到:(param1: boolean): void;

用户提出两个疑问:

  • 是否存在能修改所有重载返回类型的类型工具?
  • TypeScript中的重载是否以联合类型的形式表示?

解决方案

1. 调整重载函数的签名顺序

TypeScript对重载签名的识别遵循从具体到通用的顺序要求,必须将最通用的重载签名放在最后,才能正确识别所有重载。补充完整的重载签名列表:

function fooBar(param1: string, param2: number): number;
function fooBar(param1: boolean): number;
// 添加最通用的重载签名作为最后一项
function fooBar(boolOrString: boolean | string, param2?: number): number;
function fooBar(boolOrString: boolean | string, param2?: number): number {
  if (typeof boolOrString === 'string') {
    return boolOrString.length + param2!;
  }
  return boolOrString ? 100 : -100;
}

2. 简化VoidFn类型工具

无需复杂的联合类型分支处理,直接通过条件类型推断即可覆盖所有重载:

type VoidFn<F> = F extends ((...args: infer Args) => any) ? ((...args: Args) => void) : never

此时再使用type FV = VoidFn<typeof fooBar>,就能得到所有重载返回类型改为void的完整结果:

type FV = VoidFn<typeof fooBar>
// 最终得到:
// (param1: string, param2: number): void;
// (param1: boolean): void;
// (boolOrString: boolean | string, param2?: number): void;

关于重载与联合类型的说明

TypeScript中的函数重载并不是以联合类型表示的,而是以重载签名列表的形式存在。当你通过typeof获取重载函数的类型时,TypeScript会保留所有符合顺序要求的重载签名,前提是重载签名遵循“具体签名在前,通用签名在后”的规则。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 17:03:30