编程后端开发者

如何在TypeScript类中实现方法重载,编写重载方法时应避免哪些错误,以及可能遇到哪些类型化的细节?

用 Hintsage AI 助手通过面试

回答。

问题历史:

TypeScript支持方法重载,类似于其他强类型语言(如Java或C#),但是TypeScript中的重载语法在概念上有所不同。这里允许多个签名,但只有一个实现。这可能会导致对传统重载概念熟悉的开发者感到困惑。

问题:

常见错误是试图定义多个具有不同参数集的方法。因此会导致编译错误,因为TypeScript要求有一个实现来满足所有签名变体。

解决方案:

通过声明多个方法签名,然后提供一个满足所有变体的实现来实现重载。为了正确区分参数,通常使用类型保护或instanceof。

代码示例:

class MyLogger { log(message: string): void; log(message: string, level: 'info' | 'error'): void; log(message: string, level?: 'info' | 'error'): void { const lvl = level ?? 'info'; console.log(`[${lvl}] ${message}`); } }

关键特点:

  • 只有一个方法实现,但有多个声明-签名
  • 需要在实现中处理所有输入参数的变体
  • 实现中的类型应该尽可能宽泛

带陷阱的问题。

可以实现一个方法的两个实现,具有不同的参数集吗?

不可以。在TypeScript中,仅允许一个实现。多个同名方法是语法错误。

如何在方法重载中对rest参数进行类型化,以确保不失去严格类型?

建议在签名中描述确切参数,而在实现中使用尽可能通用的:

class Test { doWork(a: number): void; doWork(a: string): void; doWork(a: number | string): void { //... } }

如果重载签名的返回类型不同,会发生什么?

TypeScript将要求实现返回一个联合类型(Union)。否则将出现编译错误。

class X { get(value: number): string; get(value: string): number; get(value: number | string): string | number { return typeof value === 'number' ? 'number' : 42; } }

类型错误和反模式

  • 实现与重载签名不匹配
  • 一个方法的多个独立实现
  • 忽略对方法体内输入参数类型的检查

生活中的例子

负面案例

在产品中试图为类中的不同参数类型实现两个同名方法。编译后,该方法被“最后声明”替换,所有其他版本被忽略,导致了bug。

优点:

  • 对某些语言风格的熟悉

缺点:

  • 在TypeScript中完全无法工作,编译时出错
  • 增加了漏掉情况的风险

正面案例

做了多个具有union-type参数的签名,并通过类型保护在方法中处理所有变体。编译器立即提醒了类型问题。

优点:

  • 严格的类型控制
  • 安全性
  • 测试简便性

缺点:

  • 需要更多代码来检查变体