高级类型 #
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 等)简化类型定义。
- 在大型项目中,合理利用高级类型提升类型系统的表达能力和可维护性。