# TypeScript 高级类型

深入掌握 TypeScript 的高级类型系统，用于构建类型安全、可复用的组件与工具。

## 适用场景

- 开发类型安全的库或框架
- 创建可复用的泛型组件
- 实现复杂的类型推导逻辑
- 设计类型安全的 API 客户端
- 构建表单验证系统
- 创建强类型的配置对象
- 实现类型安全的状态管理
- 将 JavaScript 项目迁移至 TypeScript

## 核心概念

### 1. 泛型（Generics）

**作用**：在保持类型安全的前提下，创建可复用、类型灵活的组件。

**基础泛型函数**：
```ts
function identity<T>(value: T): T {
  return value;
}

const num = identity(42); // 类型：number
const str = identity("hello"); // 类型：string
const auto = identity(true); // 类型自动推导：boolean
```

**泛型约束（Constraints）**：
```ts
interface HasLength {
  length: number;
}

function logLength<T extends HasLength>(item: T): T {
  console.log(item.length);
  return item;
}

logLength("hello"); // ✅ OK：string 具有 length
logLength([1, 2, 3]); // ✅ OK：array 具有 length
logLength({ length: 10 }); // ✅ OK：对象具有 length
// logLength(42); // ❌ 错误：number 没有 length
```

**多类型参数**：
```ts
function merge<T, U>(obj1: T, obj2: U): T & U {
  return { ...obj1, ...obj2 };
}

const merged = merge({ name: "John" }, { age: 30 });
// 类型：{ name: string } & { age: number }
```

### 2. 条件类型（Conditional Types）

**作用**：根据类型条件动态生成类型，实现高阶类型逻辑。

**基础条件类型**：
```ts
type IsString<T> = T extends string ? true : false;

type A = IsString<string>; // true
type B = IsString<number>; // false
```

**提取返回类型（配合 `infer`）**：
```ts
type ReturnType<T> = T extends (...args: any[]) => infer R ? R : never;

function getUser() {
  return { id: 1, name: "John" };
}

type User = ReturnType<typeof getUser>;
// 类型：{ id: number; name: string; }
```

**分布式条件类型**：
```ts
type ToArray<T> = T extends any ? T[] : never;

type StrOrNumArray = ToArray<string | number>;
// 类型：string[] | number[]
```

**嵌套条件判断**：
```ts
type TypeName<T> = T extends string
  ? "string"
  : T extends number
    ? "number"
    : T extends boolean
      ? "boolean"
      : T extends undefined
        ? "undefined"
        : T extends Function
          ? "function"
          : "object";

type T1 = TypeName<string>; // "string"
type T2 = TypeName<() => void>; // "function"
```

### 3. 映射类型（Mapped Types）

**作用**：通过遍历已有类型的属性，批量转换其结构（如只读、可选、重命名等）。

**基础映射类型**：
```ts
type Readonly<T> = {
  readonly [P in keyof T]: T[P];
};

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

type ReadonlyUser = Readonly<User>;
// 类型：{ readonly id: number; readonly name: string; }
```

**可选属性**：
```ts
type Partial<T> = {
  [P in keyof T]?: T[P];
};

type PartialUser = Partial<User>;
// 类型：{ id?: number; name?: string; }
```

**键名重映射（Key Remapping）**：
```ts
type Getters<T> = {
  [K in keyof T as `get${Capitalize<K>}`]: () => T[K];
};

interface Person {
  name: string;
  age: number;
}

type PersonGetters = Getters<Person>;
// 类型：{ getName: () => string; getAge: () => number; }
```

**按值类型筛选属性**：
```ts
type PickByType<T, U> = {
  [K in keyof T as T[K] extends U ? K : never]: T[K];
};

interface Mixed {
  id: number;
  name: string;
  age: number;
  active: boolean;
}

type OnlyNumbers = PickByType<Mixed, number>;
// 类型：{ id: number; age: number; }
```

### 4. 模板字面量类型（Template Literal Types）

**作用**：基于字符串字面量进行编译期模式匹配与组合，支持大小写转换、路径拼接等。

**基础模板字面量**：
```ts
type EventName = "click" | "focus" | "blur";
type EventHandler = `on${Capitalize<EventName>}`;
// 类型："onClick" | "onFocus" | "onBlur"
```

**字符串操作工具类型**：
```ts
type UppercaseGreeting = Uppercase<"hello">; // "HELLO"
type LowercaseGreeting = Lowercase<"HELLO">; // "hello"
type CapitalizedName = Capitalize<"john">; // "John"
type UncapitalizedName = Uncapitalize<"John">; // "john"
```

**递归路径类型（Nested Path Building）**：
```ts
type Path<T> = T extends object
  ? {
      [K in keyof T]: K extends string ? `${K}` | `${K}.${Path<T[K]>}` : never;
    }[keyof T]
  : never;

interface Config {
  server: {
    host: string;
    port: number;
  };
  database: {
    url: string;
  };
}

type ConfigPath = Path<Config>;
// 类型："server" | "database" | "server.host" | "server.port" | "database.url"
```

### 5. 工具类型（Utility Types）

**常用内置工具类型**：
```ts
// Partial<T> —— 所有属性变为可选
type PartialUser = Partial<User>;

// Required<T> —— 所有属性变为必填
type RequiredUser = Required<User>;

// Readonly<T> —— 所有属性变为只读
type ReadonlyUser = Readonly<User>;

// Pick<T, K> —— 选取指定属性
type UserName = Pick<User, "name">;

// Omit<T, K> —— 排除指定属性
type UserWithoutPassword = Omit<User, "password">;

// Exclude<T, U> —— 从联合类型中排除 U
type T1 = Exclude<"a" | "b" | "c", "a">; // "b" | "c"

// Extract<T, U> —— 从联合类型中提取 U
type T2 = Extract<"a" | "b" | "c", "a" | "b">; // "a" | "b"

// NonNullable<T> —— 排除 null 和 undefined
type T3 = NonNullable<string | null | undefined>; // string

// Record<K, T> —— 创建键为 K、值为 T 的对象类型
type PageInfo = Record<string, { title: string }>
```

## 高级实践模式

### 模式 1：类型安全的事件发射器
```ts
type EventMap = {
  "user:created": { id: string; name: string };
  "user:updated": { id: string };
  "user:deleted": { id: string };
};

class TypedEventEmitter<T extends EventMap> {
  private listeners: {
    [K in keyof T]?: Array<(data: T[K]) => void>;
  } = {};

  on<K extends keyof T>(event: K, callback: (data: T[K]) => void): void {
    if (!this.listeners[event]) {
      this.listeners[event] = [];
    }
    this.listeners[event]!.push(callback);
  }

  emit<K extends keyof T>(event: K, data: T[K]): void {
    const callbacks = this.listeners[event];
    if (callbacks) {
      callbacks.forEach((callback) => callback(data));
    }
  }
}

const emitter = new TypedEventEmitter<EventMap>();

emitter.on("user:created", (data) => {
  console.log(data.id, data.name); // ✅ 类型安全！
});

emitter.emit("user:created", { id: "1", name: "John" });
// emitter.emit("user:created", { id: "1" }); // ❌ 编译错误：缺少 'name'
```

### 模式 2：类型安全的 API 客户端
```ts
type HTTPMethod = "GET" | "POST" | "PUT" | "DELETE";

type EndpointConfig = {
  "/users": {
    GET: { response: User[] };
    POST: { body: { name: string; email: string }; response: User };
  };
  "/users/:id": {
    GET: { params: { id: string }; response: User };
    PUT: { params: { id: string }; body: Partial<User>; response: User };
    DELETE: { params: { id: string }; response: void };
  };
};

type ExtractParams<T> = T extends { params: infer P } ? P : never;
type ExtractBody<T> = T extends { body: infer B } ? B : never;
type ExtractResponse<T> = T extends { response: infer R } ? R : never;

class APIClient<T extends EndpointConfig> {
  async request<Path extends keyof T, Method extends HTTPMethod>(
    path: Path,
    method: Method,
    ...[options]: ExtractParams<T[Path][Method]> extends never
      ? ExtractBody<T[Path][Method]> extends never
        ? []
        : [{ body: ExtractBody<T[Path][Method]> }]
      : [
          {
            params: ExtractParams<T[Path][Method]>;
            body?: ExtractBody<T[Path][Method]>;
          },
        ]
  ): Promise<ExtractResponse<T[Path][Method]>> {
    // 实际实现略
    return {} as any;
  }
}

const api = new APIClient<EndpointConfig>();

// ✅ 类型安全调用
const users = await api.request("/users", "GET"); // 类型：User[]

const newUser = await api.request("/users", "POST", {
  body: { name: "John", email: "john@example.com" },
}); // 类型：User

const user = await api.request("/users/:id", "GET", {
  params: { id: "123" },
}); // 类型：User
```

### 模式 3：类型安全的构建器模式
```ts
type BuilderState<T> = {
  [K in keyof T]: T[K] | undefined;
};

type RequiredKeys<T> = {
  [K in keyof T]-?: {} extends Pick<T, K> ? never : K;
}[keyof T];

type OptionalKeys<T> = {
  [K in keyof T]-?: {} extends Pick<T, K> ? K : never;
}[keyof T];

type IsComplete<S, T> =
  RequiredKeys<T> extends keyof S
    ? S[RequiredKeys<T>] extends undefined
      ? false
      : true
    : false;

class Builder<T, S extends BuilderState<T> = {}> {
  private state: S = {} as S;

  set<K extends keyof T>(key: K, value: T[K]): Builder<T, S & Record<K, T[K]>> {
    this.state[key] = value as any;
    return this as any;
  }

  build(this: IsComplete<S, T> extends true ? this : never): T {
    return this.state as T;
  }
}

interface User {
  id: string;
  name: string;
  email: string;
  age?: number;
}

const builder = new Builder<User>();

const user = builder
  .set("id", "1")
  .set("name", "John")
  .set("email", "john@example.com")
  .build(); // ✅ OK：所有必需字段已设置

// const incomplete = builder
//   .set("id", "1")
//   .build(); // ❌ 错误：缺少必需字段
```

### 模式 4：深度只读 / 深度可选
```ts
type DeepReadonly<T> = {
  readonly [P in keyof T]: T[P] extends object
    ? T[P] extends Function
      ? T[P]
      : DeepReadonly<T[P]>
    : T[P];
};

type DeepPartial<T> = {
  [P in keyof T]?: T[P] extends object
    ? T[P] extends Array<any>
      ? Array<DeepPartial<T[P][number]>>
      : DeepPartial<T[P]>
    : T[P];
};

interface Config {
  server: {
    host: string;
    port: number;
    ssl: {
      enabled: boolean;
      cert: string;
    };
  };
  database: {
    url: string;
    pool: {
      min: number;
      max: number;
    };
  };
}

type ReadonlyConfig = DeepReadonly<Config>;
// ✅ 所有嵌套属性均为只读

type PartialConfig = DeepPartial<Config>;
// ✅ 所有嵌套属性均为可选
```

### 模式 5：类型安全的表单验证
```ts
type ValidationRule<T> = {
  validate: (value: T) => boolean;
  message: string;
};

type FieldValidation<T> = {
  [K in keyof T]?: ValidationRule<T[K]>[];
};

type ValidationErrors<T> = {
  [K in keyof T]?: string[];
};

class FormValidator<T> {
  constructor(private rules: FieldValidation<T>) {}

  validate(data: T): ValidationErrors<T> | null {
    const errors: ValidationErrors<T> = {};
    let hasErrors = false;

    for (const key in this.rules) {
      const fieldRules = this.rules[key];
      const value = data[key as keyof T];

      if (fieldRules) {
        const fieldErrors: string[] = [];

        for (const rule of fieldRules) {
          if (!rule.validate(value)) {
            fieldErrors.push(rule.message);
          }
        }

        if (fieldErrors.length > 0) {
          errors[key as keyof T] = fieldErrors;
          hasErrors = true;
        }
      }
    }

    return hasErrors ? errors : null;
  }
}

interface LoginForm {
  email: string;
  password: string;
}

const validator = new FormValidator<LoginForm>({
  email: [
    {
      validate: (v) => v.includes("@"),
      message: "Email 必须包含 @",
    },
    {
      validate: (v) => v.length > 0,
      message: "Email 为必填项",
    },
  ],
  password: [
    {
      validate: (v) => v.length >= 8,
      message: "密码长度至少为 8 位",
    },
  ],
});

const errors = validator.validate({
  email: "invalid",
  password: "short",
});
// 类型：{ email?: string[]; password?: string[]; } | null
```

### 模式 6：可辨识联合（Discriminated Unions）
```ts
type Success<T> = {
  status: "success";
  data: T;
};

type Error = {
  status: "error";
  error: string;
};

type Loading = {
  status: "loading";
};

type AsyncState<T> = Success<T> | Error | Loading;

function handleState<T>(state: AsyncState<T>): void {
  switch (state.status) {
    case "success":
      console.log(state.data); // ✅ 类型：T
      break;
    case "error":
      console.log(state.error); // ✅ 类型：string
      break;
    case "loading":
      console.log("Loading...");
      break;
  }
}
```