问题历史:
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。
优点:
缺点:
做了多个具有union-type参数的签名,并通过类型保护在方法中处理所有变体。编译器立即提醒了类型问题。
优点:
缺点: