注意: 如果您是 TypeScript 新手,请先查看我们的 TypeScript 入门 教程。
函数重载允许你为单个函数名定义多个函数签名。
每个签名描述了函数的不同调用方式,函数签名要么具有
- 不同的参数类型,要么
- 不同的参数数量。
因此,同一个函数会根据传递的参数而表现出不同的行为。
注意事项
- 函数重载通过清晰地指定函数的使用方式,有助于编写更具表现力和类型安全的代码。
- 箭头函数不能重载。
如何在TypeScript中实现函数重载?
TypeScript中的函数重载与其在C、C++和Java等语言中的对应项略有不同。
在TypeScript中,你是这样做的:
步骤1:定义不同的函数签名
假设我们需要重载一个名为add()
的函数,该函数接受两个数字参数或两个字符串参数(但不能混合)。
这就是你定义函数签名的方式:
// Signature for function with number arguments
function add(a: number, b: number): number;
// Signature for function with string arguments
function add(a: string, b: string): string;
步骤2:编写单个函数体来实现重载
像C++和Java这样的语言允许你为重载编写多个函数体。
但在TypeScript中,我们编写一个函数体来实现重载函数。
// Function implementation with arguments of any type
function add(a: any, b: any): any {
// Function body
}
注意事项
- 重载签名没有函数体。
- 每个函数名只允许一个实现,但你可以在它上面声明多个重载签名。
- 实现函数必须与所有重载签名兼容。
步骤3:使用if...else实现适当的代码。
在函数体内部,使用if...else
语句检查参数类型并执行适当的代码。
如果参数的类型与函数签名中的类型不匹配,则抛出错误。
由于我们的重载函数可以接受两个数字参数或两个字符串参数,任何其他参数组合都将是无效的。
// Function implementation
function add(a: any, b: any): any {
if (typeof a === "number" && typeof b === "number") {
return a + b; // Add numbers
}
else if (typeof a === "string" && typeof b === "string") {
return a + b; // Concatenate strings
}
// Throw error if arguments are invalid
throw new Error("Invalid arguments");
}
接下来,我们将这些代码组合成一个完全可执行的程序。
使用不同参数类型进行重载
这是我们到目前为止学到的代码的组合。
// Signature for function with number arguments
function add(a: number, b: number): number;
// Signature for function with string arguments
function add(a: string, b: string): string;
// Function implementation
function add(a: any, b: any): any {
if (typeof a === "number" && typeof b === "number") {
return a + b; // Add numbers
}
else if (typeof a === "string" && typeof b === "string") {
return a + b; // Concatenate strings
}
// Throw error if arguments are invalid
throw new Error("Invalid arguments");
}
// Pass two number arguments to add()
let sum = add(5, 9);
console.log(sum);
// Pass two string arguments to add()
let concatenate = add("Winter", " is coming!");
console.log(concatenate);
// Invalid code: passing a number and a string
// let result = add(343, " Industries");
输出
14 Winter is coming!
在这里,我们为add()
函数定义了两个函数签名:一个接受两个number
参数,另一个接受两个string
参数。
程序的工作原理如下:
add(5, 9)
- 由于两个参数都是数字,add()
函数对它们执行数字加法。add("Winter", " is coming!")
- 由于两个参数都是字符串,add()
函数将这两个字符串连接起来。add(343, " Industries")
- 此函数调用无效,因为第一个参数是数字,而第二个参数是字符串。两个参数都应该是数字,或者都应该是字符串。
更多关于不同类型的重载
在许多情况下,建议使用联合类型而不是为不同参数类型重载函数。
让我们重写前面的示例作为演示。
// Function with arguments of union type
// The arguments can be either string or number
function add(a: number | string, b: number | string) {
if (typeof a === "number" && typeof b === "number") {
return a + b; // Add numbers
}
else if (typeof a === "string" && typeof b === "string") {
return a + b; // Concatenate strings
}
// Throw error if arguments are invalid
throw new Error("Invalid arguments");
}
// Pass two number arguments to add()
let sum = add(5, 9);
console.log(sum);
// Pass two string arguments to add()
let concatenate = add("Winter", " is coming!");
console.log(concatenate);
// Invalid code: passing a number and a string
// let result = add(343, " Industries");
// Output:
// 14
// Winter is coming!
使用不同参数数量进行重载
你也可以通过不同的参数数量来重载函数。例如,一个函数签名可以有一个参数,而另一个可以有两个或更多参数。
让我们通过下面的例子来实现这一点。
// Signature with no argument
function greet(): string;
// Signature with a single argument
function greet(name: string): string;
// Signature with two arguments
function greet(name: string, age: number): string;
// Function implementation
// Use optional parameters to account for different argument numbers
function greet(name?: string, age?: number): string {
// Check if two arguments are passed to the function
if (name && age !== undefined) {
return `Hello, ${name}! You are ${age} years old.`;
}
// Check if a single argument is passed
else if (name) {
return `Hello, ${name}!`;
}
// If no argument is passed
else {
return "Hello!";
}
}
// Call without passing any argument
let message: string = greet();
console.log(message);
// Call by passing a single argument
message = greet("Alice");
console.log(message);
// Call by passing two arguments
message = greet("Bob", 30);
console.log(message);
输出
Hello! Hello, Alice! Hello, Bob! You are 30 years old.
在这里,greet()
可以带有零个、一个或两个参数来调用。
该实现使用可选参数和条件逻辑来处理所有情况。传递不匹配指定类型和条件的参数将导致错误。
阅读更多