TypeScript内置辅助类型详解

156 阅读4分钟

1. Required<T> 类型

Required<T> 是 TypeScript 内置的泛型类型,它会将对象类型 T 的所有属性变为必需的,即使原本某些属性是可选的。

示例

typescript
CopyEdit
interface User {
  name: string;
  age?: number;  // 可选属性
}

type RequiredUser = Required<User>;

const user: RequiredUser = {
  name: 'John',
  age: 25,  // 现在 `age` 是必需的
};
  • 解释:在上面的例子中,User 接口中的 age 属性是可选的。通过使用 Required<User>,生成了一个新类型 RequiredUser,使得 age 成为了必需属性。

源代码

Required 类型实际上是通过映射类型实现的,它将对象的所有可选属性转换为必需的:

typescript
CopyEdit
type Required<T> = {
  [P in keyof T]-?: T[P];  // -? 确保每个属性都变成必需的
};

2. Partial<T> 类型

Partial<T> 是与 Required<T> 相对的辅助类型,它将类型 T 的所有属性变为 可选

示例

typescript
CopyEdit
interface User {
  name: string;
  age: number;
}

type PartialUser = Partial<User>;

const user: PartialUser = {
  name: 'John',  // `age` 是可选的
};
  • 解释:在上面的例子中,Partial<User>User 类型的所有属性变为可选的。

源代码

Partial<T> 类型通过映射类型将对象的所有属性变成可选:

typescript
CopyEdit
type Partial<T> = {
  [P in keyof T]?: T[P];  // ? 表示每个属性变为可选的
};

3. Readonly<T> 类型

Readonly<T> 将类型 T 中的所有属性变为 只读,即不能修改这些属性。

示例

typescript
CopyEdit
interface User {
  name: string;
  age: number;
}

type ReadonlyUser = Readonly<User>;

const user: ReadonlyUser = {
  name: 'John',
  age: 25,
};

// user.age = 30; // 错误:不能修改只读属性
  • 解释:在上面的例子中,Readonly<User>User 中的所有属性变为只读,意味着你不能再修改这些属性。

源代码

Readonly<T> 类型通过映射类型将所有属性变为只读:

typescript
CopyEdit
type Readonly<T> = {
  readonly [P in keyof T]: T[P];  // readonly 表示每个属性变为只读
};

4. Record<K, T> 类型

Record<K, T> 是一个内置的辅助类型,它用来构造一个对象类型,该对象的键是 K,值是 T。常用于通过指定一组键和值类型,构造一个对象类型。

示例

typescript
CopyEdit
type UserRoles = 'admin' | 'user' | 'guest';
type UserPermissions = Record<UserRoles, boolean>;

const permissions: UserPermissions = {
  admin: true,
  user: false,
  guest: true,
};
  • 解释:在上面的例子中,Record<UserRoles, boolean> 构造了一个对象类型,其中 UserRoles 的每个值(adminuserguest)都是对象的键,且每个键的值都是 boolean 类型。

5. Pick<T, K> 类型

Pick<T, K> 类型从类型 T 中选择一组属性 K,生成一个新的类型。K 可以是 T 的键的子集。

示例

typescript
CopyEdit
interface User {
  name: string;
  age: number;
  address: string;
}

type NameAndAge = Pick<User, 'name' | 'age'>;

const user: NameAndAge = {
  name: 'John',
  age: 25,
};
  • 解释:在上面的例子中,Pick<User, 'name' | 'age'>User 类型中提取了 nameage 属性,生成了一个新类型 NameAndAge

6. Omit<T, K> 类型

Omit<T, K> 类型是 Pick 的反向操作,它从类型 T 中去除属性 K,生成一个新的类型。

示例

typescript
CopyEdit
interface User {
  name: string;
  age: number;
  address: string;
}

type UserWithoutAddress = Omit<User, 'address'>;

const user: UserWithoutAddress = {
  name: 'John',
  age: 25,
};
  • 解释:在上面的例子中,Omit<User, 'address'>User 类型中去除了 address 属性,生成了一个新类型 UserWithoutAddress

7. Exclude<T, U> 类型

Exclude<T, U> 从类型 T 中排除掉类型 U 中的所有成员,生成一个新的类型。

示例

typescript
CopyEdit
type AllNumbers = number | string | boolean;
type OnlyNumbers = Exclude<AllNumbers, string | boolean>;

const num: OnlyNumbers = 42;  // OK
  • 解释:在上面的例子中,Exclude<AllNumbers, string | boolean> 从联合类型 AllNumbers 中排除了 stringboolean,只保留了 number

8. Extract<T, U> 类型

Extract<T, U> 从类型 T 中提取出 U 类型中的所有成员,生成一个新的类型。

示例

typescript
CopyEdit
type AllNumbers = number | string | boolean;
type OnlyNumbers = Extract<AllNumbers, number>;

const num: OnlyNumbers = 42;  // OK
  • 解释:在上面的例子中,Extract<AllNumbers, number> 提取了 AllNumbers 中的 number 类型,生成了一个新的类型 OnlyNumbers

9. NonNullable<T> 类型

NonNullable<T> 会从类型 T 中去除 nullundefined

示例

typescript
CopyEdit
type Nullable = string | null | undefined;
type NonNullableString = NonNullable<Nullable>;

const str: NonNullableString = 'Hello';  // OK
// const invalid: NonNullableString = null;  // 错误
  • 解释:在上面的例子中,NonNullable<Nullable> 会去除 nullundefined,返回一个不包含 nullundefined 的类型。

总结

TypeScript 提供了许多强大的内置类型来帮助你操作类型结构:

  1. Required<T> :将所有属性变为必需。
  2. Partial<T> :将所有属性变为可选。
  3. Readonly<T> :将所有属性变为只读。
  4. Record<K, T> :通过一组键和值类型构建对象类型。
  5. Pick<T, K> :从类型 T 中选择某些属性。
  6. Omit<T, K> :从类型 T 中去除某些属性。
  7. Exclude<T, U> :从类型 T 中排除 U 中的成员。
  8. Extract<T, U> :从类型 T 中提取 U 中的成员。
  9. NonNullable<T> :去除 nullundefined