ts映射类型

898 阅读2分钟

在映射类型里,新类型以相同的形式去转换旧类型的每个属性。

Partial

将每个属性转换为可选属性

type Partial<T> = {
    [P in keyof T]?: T[P];
}

例子:

type PersonPartial = Partial<Person>;
//   ^ = type PersonPartial = {
//       name?: string | undefined;
//       age?: number | undefined;
//   }

Readonly

将每个属性转换为只读属性

type Readonly<T> = {
    readonly [P in keyof T]: T[P];
}

例子:

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

Nullable

转换为旧类型和null的联合类型

type Nullable<T> = { 
  [P in keyof T]: T[P] | null 
}

例子:

type NullablePerson = Nullable<Person>;
//   ^ = type NullablePerson = {
//       name: string | null;
//       age: number | null;
//   }

Pick

选取一组属性指定新类型

type Pick<T, K extends keyof T> = {
  [P in K]: T[P];
}

例子:

interface Todo {
  title: string;
  description: string;
  completed: boolean;
}

type TodoPreview = Pick<Todo, "title" | "completed">;

const todo: TodoPreview = {
  title: "Clean room",
  completed: false,
};

todo;
// ^ = const todo: TodoPreview

Record

创建一组属性指定新类型,常用来声明普通Object对象

type Record<K extends keyof any, T> = {
  [P in K]: T;
}

Record属于非同态,本质上会创建新属性,不会拷贝属性修饰符。

例子:

interface PageInfo {
  title: string;
}

type Page = "home" | "about" | "contact";

const nav: Record<Page, PageInfo> = {
  about: { title: "about" },
  contact: { title: "contact" },
  home: { title: "home" },
};

nav.about;
// ^ = const nav: Record

Exclude

去除交集,返回剩余的部分

type Exclude<T, U> = T extends U ? never : T

例子:

interface Props {
  a?: number;
  b?: string;
}

const obj: Props = { a: 5 };

const obj2: Required<Props> = { a: 5 };
Property 'b' is missing in type '{ a: number; }' but required in type 'Required<Props>'.

Omit

适用于键值对对象的Exclude,去除类型中包含的键值对

type Omit = Pick<T, Exclude<keyof T, K>>

例子:

interface Todo {
  title: string;
  description: string;
  completed: boolean;
}

type TodoPreview = Omit<Todo, "description">;

const todo: TodoPreview = {
  title: "Clean room",
  completed: false,
};

ReturnType

获取返回值类型,一般为函数

type ReturnType<T extends (...args: any) => any>
  = T extends (...args: any) => infer R ? R : any;

例子:

declare function f1(): { a: number; b: string };
type T4 = ReturnType<typeof f1>;
//    ^ = type T4 = {
//        a: number;
//        b: string;
//    }

Required

将每个属性转换为必选属性

type Required<T> = {
  [P in keyof T]-?: T[P]
}

例子:

interface Props {
  a?: number;
  b?: string;
}

const obj: Props = { a: 5 };

const obj2: Required<Props> = { a: 5 };
// Property 'b' is missing in type '{ a: number; }' but required in type 'Required<Props>'.

除此以外,还有很多类似的映射类型,可以参考TypeScript: Documentation获得更详细的信息。