元素码农
基础
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:37
↑
☰
# 泛型编程 泛型是TypeScript中最强大的特性之一,它允许我们编写可重用的、类型安全的代码。本文将深入讲解TypeScript中的泛型编程。 ## 什么是泛型? 泛型就像是类型的变量,它可以代表任意类型。通过使用泛型,我们可以创建能够处理多种数据类型的组件,同时保持类型安全性。 ```typescript function identity<T>(arg: T): T { return arg; } // 使用方式 let output1 = identity<string>("myString"); // 类型是 string let output2 = identity(123); // 类型是 number ``` ## 泛型接口 我们可以创建泛型接口来定义可重用的类型契约: ```typescript interface GenericIdentityFn<T> { (arg: T): T; } let myIdentity: GenericIdentityFn<number> = identity; ``` ## 泛型类 类也可以使用泛型来创建可重用的组件: ```typescript class GenericNumber<T> { zeroValue: T; add: (x: T, y: T) => T; constructor(zero: T, addFn: (x: T, y: T) => T) { this.zeroValue = zero; this.add = addFn; } } // 使用示例 let stringNumeric = new GenericNumber<string>('', (x: string, y: string) => x + y); console.log(stringNumeric.add('Hello ', 'World')); // 输出: "Hello World" ``` ## 泛型约束 有时我们需要限制泛型可以代表的类型范围,这时可以使用泛型约束: ```typescript interface Lengthwise { length: number; } function loggingIdentity<T extends Lengthwise>(arg: T): T { console.log(arg.length); // 现在我们知道arg一定有length属性 return arg; } // 正确 loggingIdentity([1, 2, 3]); loggingIdentity("hello"); // 错误 // loggingIdentity(3); // Error: number类型没有length属性 ``` ## 在泛型约束中使用类型参数 你可以声明一个类型参数,这个类型参数被其他类型参数约束: ```typescript function getProperty<T, K extends keyof T>(obj: T, key: K) { return obj[key]; } let x = { a: 1, b: 2, c: 3, d: 4 }; getProperty(x, "a"); // 正确 // getProperty(x, "m"); // 错误: 参数m不存在于{a, b, c, d}中 ``` ## 最佳实践 1. **命名约定**:通常使用单个大写字母作为类型参数名称: - T 表示Type - K 表示Key - V 表示Value - E 表示Element 2. **适度使用**:不要过度使用泛型。如果一个函数只会处理一种类型,就不需要使用泛型。 3. **提供默认类型**:当可能的时候,为泛型参数提供默认类型: ```typescript interface Container<T = string> { value: T; } let stringContainer: Container = { value: "Hello" }; // T 默认为 string let numberContainer: Container<number> = { value: 123 }; ``` ## 常见应用场景 1. **数组操作** ```typescript function reverse<T>(array: T[]): T[] { return array.reverse(); } ``` 2. **状态管理** ```typescript class State<T> { private state: T; constructor(initialState: T) { this.state = initialState; } getState(): T { return this.state; } setState(newState: T): void { this.state = newState; } } ``` 3. **API响应处理** ```typescript interface ApiResponse<T> { data: T; status: number; message: string; } async function fetchData<T>(url: string): Promise<ApiResponse<T>> { const response = await fetch(url); return response.json(); } ``` ## 总结 泛型是TypeScript中实现灵活且类型安全的代码复用的关键特性。通过本文的学习,你应该已经掌握了: - 泛型的基本概念和语法 - 如何创建泛型接口和类 - 如何使用泛型约束 - 泛型的最佳实践和常见应用场景 合理使用泛型可以帮助我们编写更加灵活、可维护的代码,同时保持强类型检查的优势。在实际开发中,要根据具体需求来决定是否使用泛型,避免过度设计。