编程TypeScript 开发者

TypeScript 中的函数类型的重载是如何工作的,它与其他语言中的方法重载有什么不同?

用 Hintsage AI 助手通过面试

答案。

问题的历史

在 Java 或 C# 等语言中,函数和方法的重载是标准功能:可以声明多个名称相同但参数不同的函数。在 JavaScript 中没有这个功能,这增加了潜在的错误。TypeScript 在类型层面上解决了这个问题。

问题

在 TypeScript 中没有真正的重载(多重实现)。可以声明一个函数的多个签名,但只能实现一个函数。当声明的签名与实现不同步,或签名的位置不正确时,会出现错误。

解决方案

TypeScript 通过连续声明多个签名和一个与所有重载选项兼容的真实实现来支持函数重载。

代码示例:

function sum(a: number, b: number): number; function sum(a: string, b: string): string; function sum(a: any, b: any): any { return a + b; } const a = sum(1, 2); // 3 const b = sum('foo', 'bar'); // "foobar"

关键特性:

  • 始终在所有签名之后有一个实现
  • 实现必须与所有重载选项兼容
  • TypeScript 在使用重载函数时会检查调用的正确性。

带陷阱的问题。

可以在声明所有重载签名之前定义函数实现吗?

不可以,必须先有所有重载签名,然后再实现。错误:

// 错误!先是签名,然后是实现 function foo(a: number): number { return a } // 错误 function foo(a: string): string { return a } // 错误

TypeScript 检查所有重载签名的返回值吗?

TypeScript 仅在编译时保证根据声明的签名返回类型;运行时没有类型检查。

必须在唯一实现中覆盖所有输入数据选项吗?

实现函数必须根据重载签名正确处理所有输入数据选项:

function parse(a: number): string; function parse(a: string): string; function parse(a: number | string): string { return String(a); }

常见错误和反模式

  • 实现与重载签名不匹配
  • 签名和实现的声明顺序错误
  • 隐式处理/忽略类型组合

生活中的例子

消极案例

多个重载功能被声明为不同类型的输入,但实现未处理所有情况,在边缘输入时会引发运行时错误。

优点:

  • 为函数用户提供灵活的 API

缺点:

  • 类型编译,但在实现体内缺少额外检查时功能不正确。

积极案例

每个重载功能在实现中覆盖类型条件,使用类型检查(typeof/instanceof)。

优点:

  • API 安全且可预测
  • 错误在编译阶段被捕获

缺点:

  • 由于额外检查,代码库增加。