TypeScript 泛型详解(建议收藏)
TypeScript 的泛型(Generics)是一种强大的工具,它允许我们在定义函数、接口或类时,不指定具体的数据类型,而是使用类型变量(type variables)来占位,从而在实际使用时再指定具体的类型。这种机制提高了代码的复用性和类型安全性。
一、为什么需要泛型?
1. 提高代码复用性
在没有泛型的情况下,我们可能需要为不同的数据类型编写重复的代码。例如:
```typescript
function getArrayLength(arr: number[]): number {
return arr.length;
}
function getStringLength(str: string): number {
return str.length;
}
```
使用泛型后,可以合并为一个函数:
function getLength<T>(value: T[] | string): number {
return value.length;
}
2. 增强类型安全性
泛型可以在编译时捕获类型错误,避免运行时错误。例如:
```typescript
function identity(arg: any): any {
return arg;
}
// 使用泛型
function identityGeneric
return arg;
}
let output = identityGeneric
```
二、泛型的基本语法
1. 泛型函数
使用尖括号 <>
定义类型变量:
```typescript
function genericFunction
return arg;
}
let num = genericFunction
let str = genericFunction("Hello"); // 类型推断
```
2. 泛型接口
接口也可以使用泛型:
```typescript
interface GenericInterface
value: T;
}
let obj: GenericInterface
```
3. 泛型类
类同样支持泛型:
```typescript
class GenericClass
private value: T;
constructor(value: T) {
this.value = value;
}
getValue(): T {
return this.value;
}
}
let instance = new GenericClass
console.log(instance.getValue()); // 42
```
三、泛型约束
有时我们希望泛型类型满足某些条件,这时可以使用约束(Constraints)。
1. 基本约束
使用 extends
关键字限制类型:
```typescript
interface Lengthwise {
length: number;
}
function logLength
console.log(arg.length);
}
logLength("Hello"); // 5
logLength([1, 2, 3]); // 3
// logLength(42); // Error: number 没有 length 属性
```
2. 多类型变量
泛型可以有多个类型变量:
```typescript
function mapPair
return [key, value];
}
let pair = mapPair
```
四、常用泛型工具类型
TypeScript 提供了一些内置的泛型工具类型,常用于类型操作。
1. Partial<T>
将类型 T
的所有属性变为可选:
```typescript
interface User {
id: number;
name: string;
}
let partialUser: Partial
```
2. Readonly<T>
将类型 T
的所有属性变为只读:
let readonlyUser: Readonly<User> = { id: 1, name: "Bob" };
// readonlyUser.name = "Alice"; // Error: 不能修改只读属性
3. Pick<T, K>
从类型 T
中挑选出指定的属性 K
:
let pickedUser: Pick<User, "name"> = { name: "Charlie" };
4. Record<K, T>
构造一个类型,其属性键为 K
,属性值为 T
:
let userMap: Record<string, User> = {
user1: { id: 1, name: "Alice" },
user2: { id: 2, name: "Bob" },
};
五、泛型与高级特性
1. 泛型与条件类型
TypeScript 支持条件类型,可以根据条件动态生成类型:
```typescript
type Check
let checkString: Check
let checkNumber: Check
```
2. 泛型与映射类型
映射类型允许我们基于现有类型创建新类型:
```typescript
type ReadonlyKeys
readonly [P in keyof T]: T[P];
};
let readonlyUserKeys: ReadonlyKeys
// readonlyUserKeys.id = 2; // Error: 只读属性
```
六、泛型的实践
- 优先使用泛型:当函数或类需要处理多种类型时,优先考虑使用泛型。
- 合理使用约束:通过约束限制泛型类型,避免类型错误。
- 利用工具类型:善用 TypeScript 提供的工具类型,简化代码。
- 保持类型简单:避免过度复杂的泛型嵌套,保持代码可读性。
泛型是 TypeScript 中非常重要的特性,它让代码更加灵活、复用性更高,同时保持了类型安全性。通过掌握泛型的基本语法、约束、工具类型以及高级特性,我们可以编写出更加健壮和可维护的 TypeScript 代码。
建议:在实际开发中,多尝试使用泛型来替代 any
类型,逐步提升代码的类型安全性和可维护性。
(本文来源:nzw6.com)