Skip to Content

面试导航 - 程序员面试题库大全 | 前端后端面试真题 | 面试

TypescriptTS 中的方法重载

方法重载(Method Overloading)指的是使用同一个函数名,根据不同的参数类型或者数量来定义多个函数签名。在 TypeScript 中,函数的签名通过类型定义来实现,而真正的实现逻辑则由单个函数体来完成。不同的签名帮助 TypeScript 在调用时正确地推断类型。

TypeScript 方法重载的基本原则主要有以下这两个方面:

  1. 多种签名:你可以定义多个函数签名,它们会根据传入的参数类型和数量来选择匹配的签名。

  2. 单一实现:尽管你定义了多个签名,实际的函数实现是一个,且它需要处理所有的重载情况。

基本的函数重载

假设我们要实现一个简单的 greet 函数,它接受不同的参数:一个字符串,或者一个字符串和一个数字。根据传入的参数数量或类型,返回不同的结果。

// 定义重载签名 function greet(person: string): string; // 只有一个字符串类型的参数 function greet(person: string, age: number): string; // 一个字符串和一个数字类型的参数 // 实现函数体 function greet(person: string, age?: number): string { if (age === undefined) { return `Hello, ${person}!`; // 如果没有传入年龄,返回简单问候 } else { return `Hello, ${person}. You are ${age} years old.`; // 如果有年龄,返回详细问候 } } // 使用 console.log(greet('Moment')); // 输出: Hello, Moment! console.log(greet('Moment', 25)); // 输出: Hello, Moment. You are 25 years old.

重载签名通过定义不同的函数签名来处理不同的参数组合,例如一个接受字符串,另一个接受字符串和数字。函数实现通过检查 age 是否为 undefined 来区分不同的参数,并根据传入的参数类型选择对应的重载签名。

最终输出结果如下图所示:

处理不同类型的参数

有时,我们可能希望根据不同类型的输入来做不同的处理。比如,如果传入的是一个字符串,我们希望返回该字符串的某种格式;如果传入的是一个数字,我们则进行不同的计算操作。

// 定义重载签名 function process(x: string): string; // 字符串处理 function process(x: number): number; // 数字处理 // 实现函数体 function process(x: string | number): string | number { if (typeof x === 'string') { return `Processed string: ${x}`; // 处理字符串 } else { return x * 2; // 处理数字 } } // 使用 console.log(process('Moment')); // 输出: Processed string: Moment console.log(process(10)); // 输出: 20

最终输出结果如下图所示:

函数 process 定义了两种重载签名,一个接受 string 类型参数,另一个接受 number 类型参数;在实现时,函数根据 x 的类型执行不同的操作,如果是字符串则格式化,若是数字则进行计算。

多个重载签名的组合

你还可以组合多个不同的重载签名,来处理不同类型的参数组合。例如,可以同时处理两个数字、两个字符串,或者混合数字和字符串的情况。

// 定义重载签名 function add(x: number, y: number): number; // 两个数字相加 function add(x: string, y: string): string; // 两个字符串拼接 function add(x: any, y: any): any; // 默认情况 // 实现函数体 function add(x: any, y: any): any { return x + y; // 简单的加法或拼接操作 } // 使用 console.log(add(10, 20)); // 输出: 30 console.log(add('Hello, ', 'World!')); // 输出: Hello, World!

这个例子中,add 函数有三个重载签名,第一个签名处理两个数字,第二个签名处理两个字符串,第三个签名是通用的,处理任何类型的参数;在实现时,函数直接对传入的参数执行加法或拼接操作,TypeScript 会自动根据签名匹配参数类型。

重载参数较宽泛时的注意事项

当你在重载中使用较宽泛的类型时,应该将它放在签名列表的最后。如果你把 any 或 string | number 这样的类型放在前面,TypeScript 会匹配到最后一个签名,使得前面的重载签名失效。

// 错误的重载签名顺序 function combine(x: any, y: any): any; function combine(x: number, y: number): number; function combine(x: string, y: string): string; function combine(x: any, y: any): any { return x + y; }

在这种情况下,any 会被首先匹配,导致 number 和 string 类型的重载永远无法生效。正确的顺序应该是把最宽泛的类型放到最后。

// 正确的重载签名顺序 function combine(x: number, y: number): number; function combine(x: string, y: string): string; function combine(x: any, y: any): any; function combine(x: any, y: any): any { return x + y; }

总结

TypeScript 的方法重载让我们可以用同一个函数名处理多种不同的参数组合和类型。通过定义多个重载签名并提供一个统一的函数实现,我们能够在保持类型安全的同时,使得代码更加灵活和易于扩展。使用重载时需要特别注意签名的顺序,并确保实现能够覆盖所有的重载情况。

方法重载这几点是我们要牢记的:

  1. 顺序很重要:当使用重载时,签名的顺序非常重要。TypeScript 会按照从上到下的顺序匹配签名,匹配到第一个合适的签名就停止。

  2. 实现体与签名的关系:你不能为每个重载签名编写单独的实现体。你只需要一个实现体,它需要处理所有可能的签名情况。

  3. 类型推导:虽然 TypeScript 支持重载,但你仍然需要确保函数体中能正确推导出参数类型,并处理不同的参数类型。否则,可能会导致类型不匹配的错误。

最后更新于:
Copyright © 2025Moment版权所有粤ICP备2025376666