TypeScript 中的重复函数实现
Duplicate function implementation in TypeScript
当我们在同一文件中多次定义同名函数的实现时,会出现“重复函数实现”错误。要解决该错误,请重命名第二个函数或通过指定多个签名而不是多个实现来使用重载。
下面是错误如何发生的示例。
function sum() {} // ⛔️ Error: Duplicate function implementation.ts(2393) function sum() {}
我们在同一个文件中定义了一个名为sum
两次的函数并得到了错误。这也发生在类方法中——一个类不能有多个同名的方法。
如果这是你的错误的原因,请给第二个函数另一个名称。
错误的另一个原因是遗留脚本文件出现故障。如果文件中的函数只有一个定义,请将这export {}
行添加到文件中以使其成为 ES 模块。
function sum() {} export {}; // 👈️ make file ES Module
简而言之,这有时会出现故障,因为遗留脚本文件如何使声明全球化。
函数重载的语法
类似于:
function reverse(a: string): string; function reverse(a: string[]): string[]; function reverse(a: string | string[]): string | string[] { // your implementation }
{}
请注意,我们在指定函数实现时仅使用大括号。
我们基本上为同一功能提供多种功能类型,但该功能只有一种实现。
这是具有 2 个重载签名的函数的完整示例。
function createDate(timestamp: number): Date; function createDate(year: number, month: number, day: number): Date; function createDate( yearOrTimestamp: number, month?: number, day?: number, ): Date { if (month !== undefined && day !== undefined) { return new Date(yearOrTimestamp, month, day); } return new Date(yearOrTimestamp); } const date1 = createDate(1647778643657); console.log(date1); // 👉️ Sun Mar 20 2022 const date2 = createDate(2023, 9, 24); console.log(date2); // 👉️ Tue Oct 24 2023
前两行称为重载签名,第三行是函数实现。
构造Date()
函数可以传递不同的参数来创建一个Date
对象。
在第一个签名中,该函数采用时间戳 ( number
) 参数并返回一个Date
对象。
在第二个签名中,该函数采用 3 个以逗号分隔的类型参数
number
并返回一个Date
对象。
function createDate(timestamp: number): Date; function createDate(year: number, month: number, day: number): Date; function createDate( yearOrTimestamp: number, month?: number, day?: number, ): Date { if (month !== undefined && day !== undefined) { return new Date(yearOrTimestamp, month, day); } return new Date(yearOrTimestamp); } // ⛔️ Error: No overload expects 2 arguments, // but overloads do exist that expect either 1 or 3 arguments.ts(2575) const date3 = createDate(2023, 9);
即使我们调用该createDate
函数的行满足其实现签名,但因为该函数有 2 个可选参数,我们会收到错误。
没有一个重载签名需要 2 个参数。第一个重载签名 expects1
和第二个 expects 3
。
在编写函数实现时,确保它与重载签名兼容。
function example(str: string): void; // ⛔️ Error: This overload signature is not // compatible with its implementation signature. function example(num: number): void; function example(arg: string) {}
实现签名采用类型参数string
,但第二个重载签名采用类型参数number
。
实现签名必须与所有重载签名兼容。
function example(str: string): void; function example(num: number): void; function example(arg: string | number) {}
现在,实现签名中的参数具有与所有重载签名兼容的类型。
如果您的一个重载签名比其他的需要更多的参数,请在您的实现签名中将它们标记为可选。
function example(str: string): void; function example(num: number, num2: number): void; function example(arg: string | number, num2?: number) {}
您还应该确保重载签名和实现签名的返回类型兼容。
// ⛔️ Error function example(str: string): string; function example(num: number): number; function example(arg: string | number): number {}
请注意,第一个重载签名的返回类型为string
,第二个重载签名的返回类型为number
。
实现签名的返回类型不能为number
,因为它与第一个重载签名不兼容。
// ✅ Implementation signature compatible with Overload signatures function example(str: string): string; function example(num: number): number; function example(arg: string | number): number | string {}
结论
当我们在同一文件中多次定义同名函数的实现时,会出现“重复函数实现”错误。要解决该错误,请重命名第二个函数或通过指定多个签名而不是多个实现来使用重载。