Skip to content

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 property

Pick< 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 中排除 nullundefined

示例:

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); // 3

ConstructorParameters< 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>

这些工具类型可以帮助你更方便地操作和转换类型,提高代码的可读性和可维护性。在实际开发中,应该充分利用这些工具类型来简化类型定义,避免重复代码。

© 2026 编程马·菜鸟教程 版权所有