TypeScript泛型详解_建议收藏

2025-04-22 10

Image

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(arg: T): T {
return arg;
}

let output = identityGeneric("Hello"); // 类型安全
```


二、泛型的基本语法

1. 泛型函数

使用尖括号 <> 定义类型变量:

```typescript
function genericFunction(arg: T): T {
return arg;
}

let num = genericFunction(123); // 显式指定类型
let str = genericFunction("Hello"); // 类型推断
```

2. 泛型接口

接口也可以使用泛型:

```typescript
interface GenericInterface {
value: T;
}

let obj: GenericInterface = { value: "Hello" };
```

3. 泛型类

类同样支持泛型:

```typescript
class GenericClass {
private value: T;

constructor(value: T) {
this.value = value;
}

getValue(): T {
return this.value;
}
}

let instance = new GenericClass(42);
console.log(instance.getValue()); // 42
```


三、泛型约束

有时我们希望泛型类型满足某些条件,这时可以使用约束(Constraints)。

1. 基本约束

使用 extends 关键字限制类型:

```typescript
interface Lengthwise {
length: number;
}

function logLength(arg: T): void {
console.log(arg.length);
}

logLength("Hello"); // 5
logLength([1, 2, 3]); // 3
// logLength(42); // Error: number 没有 length 属性
```

2. 多类型变量

泛型可以有多个类型变量:

```typescript
function mapPair(key: K, value: V): [K, V] {
return [key, value];
}

let pair = mapPair("age", 25); // ["age", 25]
```


四、常用泛型工具类型

TypeScript 提供了一些内置的泛型工具类型,常用于类型操作。

1. Partial<T>

将类型 T 的所有属性变为可选:

```typescript
interface User {
id: number;
name: string;
}

let partialUser: Partial = { name: "Alice" }; // id 可选
```

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 = T extends string ? "String" : "Non-String";

let checkString: Check; // "String"
let checkNumber: Check; // "Non-String"
```

2. 泛型与映射类型

映射类型允许我们基于现有类型创建新类型:

```typescript
type ReadonlyKeys = {
readonly [P in keyof T]: T[P];
};

let readonlyUserKeys: ReadonlyKeys = { id: 1, name: "Alice" };
// readonlyUserKeys.id = 2; // Error: 只读属性
```


六、泛型的实践

  1. 优先使用泛型:当函数或类需要处理多种类型时,优先考虑使用泛型。
  2. 合理使用约束:通过约束限制泛型类型,避免类型错误。
  3. 利用工具类型:善用 TypeScript 提供的工具类型,简化代码。
  4. 保持类型简单:避免过度复杂的泛型嵌套,保持代码可读性。

泛型是 TypeScript 中非常重要的特性,它让代码更加灵活、复用性更高,同时保持了类型安全性。通过掌握泛型的基本语法、约束、工具类型以及高级特性,我们可以编写出更加健壮和可维护的 TypeScript 代码。

建议:在实际开发中,多尝试使用泛型来替代 any 类型,逐步提升代码的类型安全性和可维护性。

(本文来源:nzw6.com)

1. 本站所有资源来源于用户上传和网络,因此不包含技术服务请大家谅解!如有侵权请邮件联系客服!cheeksyu@vip.qq.com
2. 本站不保证所提供下载的资源的准确性、安全性和完整性,资源仅供下载学习之用!如有链接无法下载、失效或广告,请联系客服处理!
3. 您必须在下载后的24个小时之内,从您的电脑中彻底删除上述内容资源!如用于商业或者非法用途,与本站无关,一切后果请用户自负!
4. 如果您也有好的资源或教程,您可以投稿发布,成功分享后有积分奖励和额外收入!
5.严禁将资源用于任何违法犯罪行为,不得违反国家法律,否则责任自负,一切法律责任与本站无关

源码下载