TypeScript(八)工具类型

126 阅读5分钟

工具类型

Omit

用于创建一个新的类型,该类型与给定类型相同,但去除了指定的属性。

type Person = { name: string; age: number };
type NamelessPerson = Omit<Person, "name">; // { age: number }

当我们需要一个与给定类型相同,但缺少某个属性类型的新类型时,可以使用 Omit。在上面的例子中,我们创建了一个新的类型 NamelessPerson,它与 Person 类型相同,但去除了 name 属性。

Pick

用于创建一个新的类型,该类型只包含给定类型中指定的属性。

type Person = { name: string; age: number };
type NameType = Pick<Person, "name">; // { name: string }

当我们只需要从给定类型中提取某些属性时,可以使用 Pick。在上面的例子中,我们创建了一个新的类型 NameType,它只包含 Person 类型中的 name 属性。

Record

用于创建一个新的类型,该类型的键是给定类型的键,值是给定类型的值。

type PersonID = string;
type NameType = string;
type PersonName = Record<PersonID, NameType>; // { 1: "Alice"; 2: "Bob" }

当我们需要创建一个具有特定键和值的类型时,可以使用 Record。在上面的例子中,我们创建了一个新的类型 PersonName,它的键是 PersonID 类型,值是 NameType 类型。

Required

用于创建一个新的类型,该类型与给定类型相同,但所有属性都被标记为必需的。

type Person = { name?: string; age?: number };
type NamePerson = Required<Person>; // { name: string; age: number }

当我们需要确保对象的属性都是必需的时,可以使用 Required。在上面的例子中,我们创建了一个新的类型 NamePerson,它与 Person 类型相同,但所有属性都被标记为必需的。

Readonly

用于创建一个新的类型,该类型的所有属性都被标记为只读的。

type Person = { name: string; age: number };
type ReadonlyPerson = Readonly<Person>; // { readonly name: string; readonly age: number }

当我们需要创建一个只读的对象时,可以使用 Readonly。在上面的例子中,我们创建了一个新的只读类型 ReadonlyPerson,它的属性都是只读的。

Partial

用于创建一个新的类型,该类型的所有属性都被标记为可选的。

当你想要表示一个对象可能包含多个属性,但具体哪些属性是可选的或必需的并不确定时,可以使用 Partial

type Person = { name: string; age: number };
type PartialPerson = Partial<Person>; // { name?: string; age?: number }

PartialPerson 类型表示一个对象可能包含 nameage 属性,但它们都是可选的。

Exclude

用于从一个类型中提取不包含指定属性的类型。

当你想要表示一个对象不包含某些属性时,可以使用 Exclude

type Person = { name: string; age: number };
type NamelessPerson = Exclude<Person, "name">; // { age: number }

在这个例子中,NamelessPerson 类型表示一个对象可能包含 age 属性,但不包含 name 属性。

Extract

用于从一个类型中提取指定的属性。

当你想要表示一个对象只包含某些属性时,可以使用 Extract

type Person = { name: string; age: number };
type NameType = Extract<Person, "name">; // { name: string }

在这个例子中,NameType 类型表示一个对象只包含 name 属性。

NonNullable

用于创建一个新的类型,该类型不包含给定类型中的 null 或 undefined 值。

当你想要表示一个值不是 null 或 undefined 时,可以使用 NonNullable

type Person = { name: string | null; age: number | undefined };
type NamelessPerson = NonNullable<Person>; // { name: string; age: number }

在这个例子中,NamelessPerson 类型表示一个对象的 nameage 属性都不是 null 或 undefined。

ReturnType

用于从给定函数类型的返回值中提取类型。

type GetValue<T> = (arg: T) => T;

type ReturnTypeValue = ReturnType<GetValue<number>>; // number
// ReturnType 实现
type ReturnType<T extends (...args: any) => any> = T extends (
  ...args: any
) => infer R
  ? R
  : any;

当你需要处理函数返回值类型而不是函数参数类型时,可以使用 ReturnType。这在你定义泛型函数或库时特别有用,因为你可能只对函数的返回值感兴趣。通过使用 ReturnType,你可以更容易地推断和处理函数返回的类型。

Parameters

用于获取函数的参数类型。

type AddFunction = (a: number, b: number) => number;
type AddParameters = Parameters<AddFunction>; // [a: number, b: number]

可以使用 Parameters。这在处理函数类型或泛型函数时特别有用,例如在定义函数式接口或处理函数参数的类型时。

ConstructorParameters

用于获取类的构造函数参数类型。

class Car {
  constructor(public brand: string, public year: number) {}
}
type CarConstructorParameters = ConstructorParameters<typeof Car>; // [[string, number]]

可以使用 ConstructorParameters。这在处理类类型或泛型类时特别有用,例如在定义构造函数式接口或处理构造函数参数的类型时。

自定义工具类型()

All

All 用于创建一个新的类型,该类型的所有属性都被标记为可选的或必需的。这在你想从现有类型中提取所有必需属性时非常有用。

type OmitCondition<
  T,
  K extends keyof T,
  Keep extends keyof T = never
> = K extends Keep ? T : Omit<T, K>;

type All<T, Keep extends keyof T = never> = {
  [P in keyof T]: OmitCondition<T, P, Keep>;
};

type Person = { name: string; age: number };
type NamelessPerson = All<Person, "name">; // { name: string }

在这个例子中,All 用于从 Person 类型中提取 name 属性,并将其标记为必需的。这意味着 NamelessPerson 类型只包含 name 属性,并且该属性是必需的。

UnwrapOptional

用于从可选链中提取值类型。

type UnwrapOptional<T> = T extends undefined ? never : T;

type OptionalValue<T> = T | undefined;
type UnwrapOptionalValue<T> = UnwrapOptional<OptionalValue<T>>; // T

可以使用 UnwrapOptional。这在处理可选链时特别有用,例如在处理可能为 undefined 或 null 的值时。通过使用 UnwrapOptional,你可以更容易地处理可选链的值类型。