TypeScript 类型系统详解

2026-06-22 · 6 阅读 · 502字
JavaScriptTypeScript

TypeScript 类型系统详解

基础类型回顾

// 基本类型
let name: string = 'TypeScript';
let count: number = 42;
let isDone: boolean = false;
let items: number[] = [1, 2, 3];
let tuple: [string, number] = ['hello', 42];

// 联合类型
let id: string | number = 'abc123';
id = 456; // OK

// 字面量类型
type Status = 'active' | 'inactive' | 'pending';
let status: Status = 'active';

// 类型别名
type Point = { x: number; y: number };

接口 vs 类型别名

// Interface 可以声明合并
interface User {
  name: string;
  age: number;
}
interface User {
  email: string; // 合并到同一个 User 类型
}

// Type 支持联合、交叉等复杂类型
type Result = 'success' | 'error';
type AdminUser = User & { role: 'admin' };

// 接口可以被类 implements
class Person implements User {
  constructor(public name: string, public age: number, public email: string) {}
}

泛型

// 泛型函数
function first<T>(arr: T[]): T | undefined {
  return arr[0];
}

// 泛型约束
function getProperty<T, K extends keyof T>(obj: T, key: K): T[K] {
  return obj[key];
}

// 泛型工具类型
type Partial<T> = { [P in keyof T]?: T[P] };
type Required<T> = { [P in keyof T]-?: T[P] };
type Readonly<T> = { readonly [P in keyof T]: T[P] };

条件类型

// 基础条件类型
type IsString<T> = T extends string ? true : false;
type A = IsString<'hello'>; // true
type B = IsString<42>;       // false

// 分布式条件类型
type ToArray<T> = T extends unknown ? T[] : never;
type Result = ToArray<string | number>; // string[] | number[]

// infer 关键字
type ReturnType<T> = T extends (...args: any[]) => infer R ? R : never;
type Fn = (x: number) => string;
type R = ReturnType<Fn>; // string

映射类型

// 将属性全部变为可选
type MyPartial<T> = { [P in keyof T]?: T[P] };

// 将属性全部变为只读
type MyReadonly<T> = { readonly [P in keyof T]: T[P] };

// 挑选指定属性
type Pick<T, K extends keyof T> = { [P in K]: T[P] };

// 排除指定属性
type Omit<T, K extends keyof T> = { [P in Exclude<keyof T, K>]: T[P] };

// 重映射键(TypeScript 4.1+)
type Getters<T> = {
  [K in keyof T as `get${Capitalize<string & K>}`]: () => T[K];
};

模板字面量类型

type EventName = `on${Capitalize<string>}`;
type Color = 'red' | 'green' | 'blue';
type BrightColor = `bright-${Color}`;
// 'bright-red' | 'bright-green' | 'bright-blue'

type ApiEndpoint = `/api/${'users' | 'posts'}/${number}`;
// '/api/users/42' | '/api/posts/42'

实战:类型安全的 API 客户端

interface ApiConfig {
  baseUrl: string;
  timeout: number;
  headers: Record<string, string>;
}

type HttpMethod = 'GET' | 'POST' | 'PUT' | 'DELETE';

interface ApiResponse<T> {
  data: T;
  status: number;
  message: string;
}

async function request<T>(
  url: string,
  method: HttpMethod,
  body?: unknown
): Promise<ApiResponse<T>> {
  const response = await fetch(url, {
    method,
    headers: { 'Content-Type': 'application/json' },
    body: body ? JSON.stringify(body) : undefined,
  });
  return response.json();
}

// 类型安全的 API 调用
interface User {
  id: number;
  name: string;
  email: string;
}

const user = await request<User>('/api/users/1', 'GET');
// user.data 的类型为 User

总结

TypeScript 类型系统功能强大,从简单的类型注解到复杂的条件类型、映射类型,掌握这些工具能让代码更健壮、自文档化。建议在实际项目中逐步应用,先从基础类型和接口开始,再逐步引入泛型和高级类型。