TypeScript 函数重载

注意: 如果您是 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()可以带有零个、一个或两个参数来调用。

该实现使用可选参数和条件逻辑来处理所有情况。传递不匹配指定类型和条件的参数将导致错误。


阅读更多

你觉得这篇文章有帮助吗?

我们的高级学习平台,凭借十多年的经验和数千条反馈创建。

以前所未有的方式学习和提高您的编程技能。

试用 Programiz PRO
  • 交互式课程
  • 证书
  • AI 帮助
  • 2000+ 挑战