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

TypeScript如何将重载(可变返回类型)函数类型定义为表达式?

TypeScript重载函数表达式与延迟调用的类型问题

问题相关代码

function identity_fun(input: string): string;
function identity_fun(input: number): number;
function identity_fun(input: string | number): string | number {
  return input;
}

type MultiReturn = {
  (input: string): string;
  (input: number): number;
}

const identity_funexpr: MultiReturn = (input: string | number) => input; // 报错

const ff = (i: string | number) => () => {
  identity_fun(i); // 报错
};
const deferred_3 = ff(3);
const deferred_str = ff('str');

问题说明

  1. 用函数声明语法定义的重载函数identity_fun可以正确推断返回类型,比如调用identity_fun(3)时,返回值类型会被推断为number。
  2. 无法直接用箭头函数实现相同的重载能力,会触发TypeScript错误:

Type '(input: string | number) => string | number' is not assignable to type 'MultiReturn'.
Type 'string | number' is not assignable to type 'string'.
Type 'number' is not assignable to type 'string'.

  1. 在延迟输入值的场景下调用重载函数也会失败,报错信息:

No overload matches this call.
Overload 1 of 2, '(input: string): string', gave the following error.
Argument of type 'string | number' is not assignable to parameter of type 'string'.
Type 'number' is not assignable to type 'string'.
Overload 2 of 2, '(input: number): number', gave the following error.
Argument of type 'string | number' is not assignable to parameter of type 'number'.
Type 'string' is not assignable to type 'number'.

现有冗余实现(无法满足类型延迟确定需求)

function identity_fun(input: string): string;
function identity_fun(input: number): number;
function identity_fun(input: string | number): string | number {
  return input;
}

function isString(input: string | number): input is string {
  return typeof input === "string";
}

function ff(i: string): () => string;
function ff(i: number): () => number;
function ff(i: string | number) {
  return isString(i) ? () => identity_fun(i) : () => identity_fun(i);
}

const deferred_3 = ff(3);
const deferred_str = ff("str");

console.log(deferred_3(), deferred_str());

无冗余解决方案

1. 用泛型实现箭头函数的重载能力

不需要依赖MultiReturn类型,直接用泛型让箭头函数保持输入输出类型一致,效果和重载函数完全相同:

const identity_funexpr = <T extends string | number>(input: T): T => input;

// 类型推断正常
const num = identity_funexpr(3); // num: number
const str = identity_funexpr('str'); // str: string

如果一定要贴合MultiReturn类型,也可以用类型断言(泛型方案更优雅,优先推荐):

const identity_funexpr: MultiReturn = ((input: string | number) => input) as MultiReturn;

2. 用泛型实现延迟调用的类型匹配

通过泛型约束延迟调用函数的参数类型,让TypeScript能正确推断返回的函数类型,无需冗余的重载和类型守卫:

function identity_fun(input: string): string;
function identity_fun(input: number): number;
function identity_fun(input: string | number): string | number {
  return input;
}

const ff = <T extends string | number>(i: T) => () => identity_fun(i);

const deferred_3 = ff(3); // deferred_3: () => number
const deferred_str = ff('str'); // deferred_str: () => string

// 调用时类型正确
console.log(deferred_3(), deferred_str());

原理说明

  • 泛型可以让函数的输入输出类型保持强关联,避免联合类型导致的重载匹配失败问题。
  • 延迟调用场景下,泛型会捕获传入的具体类型(number或string),而不是统一的string | number联合类型,因此调用重载函数时能精准匹配对应的重载签名。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 15:46:31