Appearance
TypeScript 常用工具类型
TypeScript 提供了一系列内置的工具类型,这些工具类型可以帮助你更方便地操作和转换类型。本章节将介绍 TypeScript 中常用的工具类型。
Partial< T>
Partial< T> 将类型 T 的所有属性变为可选。
示例:
typescript
interface User {
id: number;
name: string;
email: string;
age: number;
}
// 所有属性变为可选
type PartialUser = Partial<User>;
const partialUser: PartialUser = {
id: 1,
name: "John" // 其他属性可选
};
// 实用场景:更新用户信息
function updateUser(id: number, updates: Partial<User>): void {
// 实现更新逻辑
console.log(`Updating user ${id} with:`, updates);
}
updateUser(1, { name: "Jane", email: "jane@example.com" });Required< T>
Required< T> 将类型 T 的所有属性变为必选。
示例:
typescript
interface User {
id: number;
name: string;
email?: string;
age?: number;
}
// 所有属性变为必选
type RequiredUser = Required<User>;
// 错误:缺少可选属性
// const requiredUser: RequiredUser = {
// id: 1,
// name: "John" // 缺少 email 和 age 属性
// };
// 正确:所有属性都必须提供
const requiredUser: RequiredUser = {
id: 1,
name: "John",
email: "john@example.com",
age: 30
};Readonly< T>
Readonly< T> 将类型 T 的所有属性变为只读。
示例:
typescript
interface User {
id: number;
name: string;
email: string;
}
// 所有属性变为只读
type ReadonlyUser = Readonly<User>;
const readonlyUser: ReadonlyUser = {
id: 1,
name: "John",
email: "john@example.com"
};
// 错误:不能修改只读属性
// readonlyUser.name = "Jane"; // Cannot assign to 'name' because it is a read-only propertyPick< T, K>
Pick< T, K> 从类型 T 中挑选出指定的属性 K。
示例:
typescript
interface User {
id: number;
name: string;
email: string;
age: number;
address: string;
}
// 只挑选 id, name, email 属性
type UserBasicInfo = Pick<User, "id" | "name" | "email">;
const userBasicInfo: UserBasicInfo = {
id: 1,
name: "John",
email: "john@example.com"
// 不需要提供 age 和 address 属性
};Omit< T, K>
Omit< T, K> 从类型 T 中剔除指定的属性 K。
示例:
typescript
interface User {
id: number;
name: string;
email: string;
age: number;
address: string;
}
// 剔除 address 属性
type UserWithoutAddress = Omit<User, "address">;
const userWithoutAddress: UserWithoutAddress = {
id: 1,
name: "John",
email: "john@example.com",
age: 30
// 不需要提供 address 属性
};
// 剔除多个属性
type UserCoreInfo = Omit<User, "address" | "age">;
const userCoreInfo: UserCoreInfo = {
id: 1,
name: "John",
email: "john@example.com"
// 不需要提供 address 和 age 属性
};Exclude< T, U>
Exclude< T, U> 从类型 T 中排除可以赋值给类型 U 的类型。
示例:
typescript
// 从联合类型中排除指定类型
type NumberOrString = number | string | boolean;
type NumberOrBoolean = Exclude<NumberOrString, string>; // number | boolean
// 排除字面量类型
type Direction = "up" | "down" | "left" | "right";
type VerticalDirection = Exclude<Direction, "left" | "right">; // "up" | "down"Extract< T, U>
Extract< T, U> 从类型 T 中提取可以赋值给类型 U 的类型。
示例:
typescript
// 从联合类型中提取指定类型
type NumberOrString = number | string | boolean;
type OnlyString = Extract<NumberOrString, string>; // string
// 提取字面量类型
type Direction = "up" | "down" | "left" | "right";
type HorizontalDirection = Extract<Direction, "left" | "right">; // "left" | "right"ReturnType< T>
ReturnType< T> 获取函数类型 T 的返回值类型。
示例:
typescript
// 获取函数返回值类型
function add(a: number, b: number): number {
return a + b;
}
type AddReturnType = ReturnType<typeof add>; // number
// 获取箭头函数返回值类型
const multiply = (a: number, b: number): number => a * b;
type MultiplyReturnType = ReturnType<typeof multiply>; // number
// 获取泛型函数返回值类型
function identity<T>(value: T): T {
return value;
}
type IdentityReturnType = ReturnType<typeof identity>; // unknown其他工具类型
Record< K, T >
Record< K, T > 创建一个属性键为 K,属性值为 T 的类型。
示例:
typescript
// 创建字符串键,数字值的类型
type NumberMap = Record<string, number>;
const scores: NumberMap = {
math: 95,
english: 88,
science: 92
};
// 创建字面量键,字符串值的类型
type DirectionMap = Record<"up" | "down" | "left" | "right", string>;
const directionLabels: DirectionMap = {
up: "向上",
down: "向下",
left: "向左",
right: "向右"
};NonNullable< T>
NonNullable< T> 从类型 T 中排除 null 和 undefined。
示例:
typescript
// 排除 null 和 undefined
type MaybeString = string | null | undefined;
type NonNullableString = NonNullable<MaybeString>; // string
// 使用
function processString(value: NonNullableString): void {
console.log(value.length); // 不需要检查 null 或 undefined
}
processString("Hello"); // 正确
// processString(null); // 错误:Argument of type 'null' is not assignable to parameter of type 'string'Parameters< T>
Parameters< T> 获取函数类型 T 的参数类型组成的元组类型。
示例:
typescript
// 获取函数参数类型
function add(a: number, b: number): number {
return a + b;
}
type AddParameters = Parameters<typeof add>; // [number, number]
// 使用
function callAdd(...args: AddParameters): number {
return add(...args);
}
callAdd(1, 2); // 3ConstructorParameters< T>
ConstructorParameters< T> 获取构造函数类型 T 的参数类型组成的元组类型。
示例:
typescript
// 定义类
class Person {
constructor(name: string, age: number) {
// 构造函数逻辑
}
}
// 获取构造函数参数类型
type PersonConstructorParams = ConstructorParameters<typeof Person>; // [string, number]
// 使用
function createPerson(...args: PersonConstructorParams): Person {
return new Person(...args);
}
const person = createPerson("John", 30);实战:使用工具类型
示例 1:表单验证
typescript
interface LoginForm {
email: string;
password: string;
rememberMe?: boolean;
}
// 创建表单状态类型
type FormState<T> = {
values: T;
errors: Partial<Record<keyof T, string>>;
touched: Partial<Record<keyof T, boolean>>;
};
// 使用
const loginFormState: FormState<LoginForm> = {
values: {
email: "",
password: "",
rememberMe: false
},
errors: {},
touched: {}
};
// 更新表单值
function updateFormValue<K extends keyof LoginForm>(
state: FormState<LoginForm>,
field: K,
value: LoginForm[K]
): FormState<LoginForm> {
return {
...state,
values: {
...state.values,
[field]: value
},
touched: {
...state.touched,
[field]: true
}
};
}
// 验证表单
function validateForm(form: LoginForm): Partial<Record<keyof LoginForm, string>> {
const errors: Partial<Record<keyof LoginForm, string>> = {};
if (!form.email) {
errors.email = "Email is required";
} else if (!form.email.includes("@")) {
errors.email = "Invalid email";
}
if (!form.password) {
errors.password = "Password is required";
} else if (form.password.length < 8) {
errors.password = "Password must be at least 8 characters";
}
return errors;
}示例 2:API 响应处理
typescript
// 定义 API 响应接口
interface ApiResponse<T> {
success: boolean;
data?: T;
error?: {
code: number;
message: string;
};
}
// 定义用户类型
interface User {
id: number;
name: string;
email: string;
age: number;
address: string;
}
// 只获取用户基本信息
type UserBasicInfo = Pick<User, "id" | "name" | "email">;
// API 响应类型
type UserResponse = ApiResponse<UserBasicInfo>;
// 处理 API 响应
function handleUserResponse(response: UserResponse): void {
if (response.success && response.data) {
console.log(`User: ${response.data.name}`);
console.log(`Email: ${response.data.email}`);
} else if (response.error) {
console.error(`Error: ${response.error.message}`);
}
}
// 模拟 API 响应
const successResponse: UserResponse = {
success: true,
data: {
id: 1,
name: "John",
email: "john@example.com"
}
};
const errorResponse: UserResponse = {
success: false,
error: {
code: 404,
message: "User not found"
}
};
handleUserResponse(successResponse);
handleUserResponse(errorResponse);小结
本章节介绍了 TypeScript 中常用的工具类型,包括:
Partial< T>:将所有属性变为可选Required< T>:将所有属性变为必选Readonly< T>:将所有属性变为只读Pick< T, K>:挑选指定属性Omit< T, K>:剔除指定属性Exclude< T, U>:排除指定类型Extract< T, U>:提取指定类型ReturnType< T>:获取函数返回值类型- 其他工具类型:
Record< K, T>、NonNullable< T>、Parameters< T>、ConstructorParameters< T>
这些工具类型可以帮助你更方便地操作和转换类型,提高代码的可读性和可维护性。在实际开发中,应该充分利用这些工具类型来简化类型定义,避免重复代码。
