元素码农
基础
UML建模
数据结构
算法
设计模式
网络
TCP/IP协议
HTTPS安全机制
WebSocket实时通信
数据库
sqlite
postgresql
clickhouse
后端
rust
go
java
php
mysql
redis
mongodb
etcd
nats
zincsearch
前端
浏览器
javascript
typescript
vue3
react
游戏
unity
unreal
C++
C#
Lua
App
android
ios
flutter
react-native
安全
Web安全
测试
软件测试
自动化测试 - Playwright
人工智能
Python
langChain
langGraph
运维
linux
docker
工具
git
svn
🌞
🌙
目录
▶
TypeScript环境准备
安装与配置
第一个TS程序
编译流程解析
▶
基础类型系统
类型注解语法
原始类型定义
数组与元组
接口与对象
▶
高级类型系统
泛型编程
条件类型
映射类型
类型推断
类型保护
高级类型工具
▶
函数开发
函数类型声明
可选参数与默认值
箭头函数应用
函数重载
泛型函数
▶
类与面向对象
类的定义
继承与修饰符
存取器使用
抽象类与接口
泛型类与抽象类
访问修饰符与属性
▶
模块化开发
模块导入导出
类型声明文件
命名空间
模块解析策略
▶
工程实践
tsconfig详解
常见编译选项
项目构建配置
代码组织最佳实践
单元测试
调试技巧
▶
常见问题
类型错误处理
类型断言技巧
类型兼容性
版本迁移指南
发布时间:
2025-03-31 09:42
↑
☰
# 函数重载 函数重载是TypeScript中的一个重要特性,它允许我们为同一个函数提供多个类型定义。本文将详细介绍函数重载的概念和应用。 ## 什么是函数重载? 函数重载允许一个函数接受不同数量或类型的参数,然后根据传入的参数做出不同的处理。在TypeScript中,我们通过定义多个函数类型声明,然后实现一个函数体来实现重载。 ## 基本语法 ```typescript // 重载签名 function add(a: number, b: number): number; function add(a: string, b: string): string; // 实现签名 function add(a: number | string, b: number | string): number | string { if (typeof a === "number" && typeof b === "number") { return a + b; } else if (typeof a === "string" && typeof b === "string") { return a.concat(b); } throw new Error("Parameters must be numbers or strings"); } // 使用示例 console.log(add(1, 2)); // 输出: 3 console.log(add("Hello", " World")); // 输出: "Hello World" ``` ## 重载规则 1. **重载签名**:定义函数可以接受的参数类型和返回值类型的组合 2. **实现签名**:包含函数的实际实现,必须兼容所有重载签名 3. **类型检查**:TypeScript会按照重载的顺序从上到下尝试匹配 ## 方法重载 类中的方法也可以使用重载: ```typescript class Calculator { // 重载签名 add(a: number, b: number): number; add(a: string, b: string): string; // 实现签名 add(a: number | string, b: number | string): number | string { if (typeof a === "number" && typeof b === "number") { return a + b; } else if (typeof a === "string" && typeof b === "string") { return a.concat(b); } throw new Error("Parameters must be numbers or strings"); } } const calc = new Calculator(); console.log(calc.add(1, 2)); // 输出: 3 console.log(calc.add("Hello", " World")); // 输出: "Hello World" ``` ## 构造函数重载 类的构造函数也可以重载: ```typescript class Point { // 重载签名 constructor(x: number, y: number); constructor(coord: [number, number]); // 实现签名 constructor(xOrCoord: number | [number, number], y?: number) { if (typeof xOrCoord === "number" && typeof y === "number") { this.x = xOrCoord; this.y = y; } else if (Array.isArray(xOrCoord)) { this.x = xOrCoord[0]; this.y = xOrCoord[1]; } } private x: number; private y: number; getCoordinates() { return [this.x, this.y]; } } // 使用示例 const p1 = new Point(10, 20); const p2 = new Point([30, 40]); ``` ## 泛型函数重载 重载也可以与泛型结合使用: ```typescript function merge<T>(arr1: T[], arr2: T[]): T[]; function merge<T, U>(arr1: T[], arr2: U[]): (T | U)[]; function merge<T, U>(arr1: T[], arr2: U[]): (T | U)[] { return [...arr1, ...arr2]; } // 使用示例 const numbers = merge([1, 2], [3, 4]); // number[] const mixed = merge([1, 2], ["a", "b"]); // (number | string)[] ``` ## 实际应用场景 ### 1. DOM操作 ```typescript interface Element { // 重载签名 addEventListener(type: "click", handler: (e: MouseEvent) => void): void; addEventListener(type: "keypress", handler: (e: KeyboardEvent) => void): void; addEventListener(type: "load", handler: (e: Event) => void): void; // 实现签名 addEventListener(type: string, handler: (e: Event) => void): void; } ``` ### 2. 数据转换 ```typescript class Converter { // 字符串转数字 convert(value: string): number; // 数字转字符串 convert(value: number): string; // 布尔值转数字 convert(value: boolean): number; convert(value: string | number | boolean): string | number { if (typeof value === "string") { return parseFloat(value); } else if (typeof value === "number") { return value.toString(); } else { return value ? 1 : 0; } } } ``` ### 3. API响应处理 ```typescript class ApiClient { // 无参数GET请求 fetch<T>(url: string): Promise<T>; // 带查询参数的GET请求 fetch<T>(url: string, params: Record<string, string>): Promise<T>; // POST请求 fetch<T>(url: string, data: unknown, method: "POST"): Promise<T>; async fetch<T>( url: string, paramsOrData?: Record<string, string> | unknown, method?: "POST" ): Promise<T> { if (method === "POST") { return fetch(url, { method: "POST", body: JSON.stringify(paramsOrData) }).then(r => r.json()); } else if (paramsOrData) { const params = new URLSearchParams(paramsOrData as Record<string, string>); return fetch(`${url}?${params}`).then(r => r.json()); } else { return fetch(url).then(r => r.json()); } } } ``` ## 最佳实践 1. **重载顺序**:将最具体的重载放在前面,最通用的放在后面 ```typescript // 好的做法 function fn(x: string): string; function fn(x: any): any; // 不好的做法 function fn(x: any): any; function fn(x: string): string; ``` 2. **避免过度重载**:只在真正需要的时候使用重载 ```typescript // 不需要重载 function getLength(x: any[]): number; function getLength(x: string): number; function getLength(x: any[] | string): number { return x.length; } // 使用联合类型更简单 function getLength(x: any[] | string): number { return x.length; } ``` 3. **使用泛型替代重载**:当可能的时候,使用泛型来代替重载 ```typescript // 使用重载 function reverse(x: string): string; function reverse<T>(x: T[]): T[]; // 使用泛型约束更好 function reverse<T extends string | any[]>(x: T): T { return typeof x === "string" ? x.split("").reverse().join("") as T : x.slice().reverse() as T; } ``` ## 总结 函数重载是TypeScript中一个强大的特性,它允许我们: - 为同一个函数提供多个类型定义 - 根据不同的参数类型提供不同的实现 - 提供更好的类型安全性和IDE支持 合理使用函数重载可以帮助我们编写更加类型安全和可维护的代码。但要注意避免过度使用重载,在可能的情况下优先考虑使用联合类型或泛型。