03 高级类型

高级类型 #

TypeScript 提供了多种高级类型,帮助开发者更灵活地描述复杂的数据结构和类型关系。

映射类型(Mapped Types) #

映射类型允许基于已有类型创建新的类型,常用于批量修改属性类型。

// 将所有属性变为可选
type Partial<T> = {
  [P in keyof T]?: T[P];
};

// 将所有属性变为只读
type Readonly<T> = {
  readonly [P in keyof T]: T[P];
};

条件类型(Conditional Types) #

条件类型根据类型参数进行条件判断,返回不同的类型。

type IsString<T> = T extends string ? true : false;

type A = IsString<'abc'>; // true
type B = IsString<123>;   // false

索引类型(Indexed Types) #

索引类型用于获取对象属性的类型。

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

type NameType = Person['name']; // string
type AgeType = Person['age'];   // number

类型工具(Utility Types) #

TypeScript 内置了多种类型工具,简化类型操作:

  • Partial<T>:将类型 T 的所有属性变为可选。
  • Required<T>:将类型 T 的所有属性变为必选。
  • Readonly<T>:将类型 T 的所有属性变为只读。
  • Pick<T, K>:从类型 T 中挑选部分属性组成新类型。
  • Record<K, T>:构造一个以 K 为键、T 为值的对象类型。
  • Exclude<T, U>:从类型 T 中排除可以赋值给 U 的类型。
  • Extract<T, U>:提取 T 中可以赋值给 U 的类型。
  • Omit<T, K>:从类型 T 中排除 K 属性。

示例代码 #

// 映射类型示例
interface User {
  id: number;
  name: string;
}

type UserPartial = Partial<User>; // { id?: number; name?: string }

// 条件类型示例
type Result<T> = T extends number ? 'Number' : 'Other';
type Test1 = Result<123>; // 'Number'
type Test2 = Result<'abc'>; // 'Other'

// 索引类型示例
function getValue<T, K extends keyof T>(obj: T, key: K): T[K] {
  return obj[key];
}

// 类型工具示例
interface Todo {
  title: string;
  completed: boolean;
}

type ReadonlyTodo = Readonly<Todo>;
type PartialTodo = Partial<Todo>;
type PickTodo = Pick<Todo, 'title'>;
type RecordTodo = Record<'a' | 'b', Todo>;

实际应用案例 #

1. 动态表单类型 #

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

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

const values: FormValues<LoginForm> = {
  username: 'admin',
  password: '123456',
};

2. API 响应数据处理 #

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

type UserResponse = ApiResponse<User>;

常见问题与注意事项 #

  • 映射类型和条件类型嵌套使用时,注意类型推断的复杂性。
  • 类型工具的使用需结合实际业务需求,避免过度设计。
  • 某些高级类型可能导致类型推断变慢,影响编译性能。

最佳实践 #

  • 善用映射类型和条件类型提升类型复用性和灵活性。
  • 使用索引类型安全地访问对象属性。
  • 结合内置类型工具(如 Partial、Readonly、Record、Omit 等)简化类型定义。
  • 在大型项目中,合理利用高级类型提升类型系统的表达能力和可维护性。