# 泛型

URL: https://caijiao.org/ts/part2/generics
Source: docs/ts/part2/generics.md
Description: TypeScript 中泛型的基本概念和用法，包括泛型函数、接口、类，以及泛型约束和默认类型等，帮助开发者灵活构建通用的类型。

泛型（Generics）是 [TypeScript](/ts/) 的一个强大特性，允许我们在定义函数、接口或类时使用占位符类型，使得代码更加灵活和复用。

## 泛型函数

泛型函数可以接收不同类型的参数，并根据传入的类型自动推断返回值的类型。

```ts
function identity<T>(arg: T): T {
  return arg;
}

let result = identity(5); // result 的类型为 number
```

## 泛型接口

泛型也可以应用于接口中，从而实现对类型的灵活约束。

```ts
interface Box<T> {
  value: T;
}

let box: Box<number> = { value: 123 };
```

## 泛型类

泛型类可以在类中使用泛型，支持多种类型的实例化。

```ts
class GenericBox<T> {
  constructor(public value: T) {}

  getValue(): T {
    return this.value;
  }
}

let stringBox = new GenericBox<string>("Hello");
let numberBox = new GenericBox<number>(123);
```

## 泛型约束与默认类型

泛型可以通过约束来限制接受的类型，确保它们符合某些条件。也可以设置默认类型，如果没有传入类型参数时使用默认值。

### 泛型约束

```ts
function logLength<T extends { length: number }>(arg: T): void {
  console.log(arg.length);
}

logLength([1, 2, 3]); // 数组
logLength("Hello"); // 字符串
```

### 默认类型

```ts
function create<T = string>(value: T): T {
  return value;
}

let result1 = create(123); // T 默认为 number
let result2 = create("Hello"); // T 默认为 string
```

## 泛型工具类型应用

TypeScript 提供了一些内置的泛型工具类型，如 `Partial<T>`、`Readonly<T>`、`Record<K, T>` 等，用于简化常见类型操作。

```ts
type User = { name: string; age: number };

type PartialUser = Partial<User>; // { name?: string; age?: number }

type ReadonlyUser = Readonly<User>; // { readonly name: string; readonly age: number }

type UserMap = Record<string, User>; // { [key: string]: User }
```

泛型提供了类型的抽象能力，使得 TypeScript 在确保类型安全的同时，能够轻松处理各种不同的类型，极大提升了代码的灵活性和复用性。
