Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Typescript utility-types 实现 #62

Open
zzkkui opened this issue Dec 3, 2020 · 0 comments
Open

Typescript utility-types 实现 #62

zzkkui opened this issue Dec 3, 2020 · 0 comments

Comments

@zzkkui
Copy link

zzkkui commented Dec 3, 2020

工具类型

官方

Partial

Readonly<Type>,将传入的属性变为可选项。

源码

// keyof 产生联合类型, in 则可以遍历枚举类型,所以他们经常一起使用
type Partial<T> = { [P in keyof T]?: T[P] };

Required

Required<Type>,将传入的属性变为必选项。

源码

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

一个有意思的用法 -?, 这里很好理解就是将可选项代表的 ? 去掉, 从而让这个类型变成必选项. 与之对应的还有个+? , 这个含义自然与-?之前相反, 它是用来把属性变成可选项的.

Readonly

Readonly<Type>,将传入的属性变为只读选项

源码

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

Record

源码

// 将 K 中所有的属性的值转化为 T 类型
type Record<K extends keyof any, T> = {
    [P in K]: T;
};

demo

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

Omit

通过从“类型”中选取所有属性,然后删除“键”来构造一个新类型。

源码

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

demo

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

// 通过类型 Todo 删除了 description 建,形成了一个新的类型
type TodoPreview = Omit<Todo, "description">;

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

Pick

通过从源类型中选择属性Keys的集合来构造类型。

源码

// extends 继承,这里约束 K 是 keyof T 的子集
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
};

Exclude

// 若 T 能够赋值给 U,那么类型是 X,否则为 Y。
T extends U ? X : Y

对于联合类型来说会自动分发条件,例如 T extends U ? X : Y, T 可能是 A | B 的联合类型, 那实际情况就变成(A extends U ? X : Y) | (B extends U ? X : Y)

源码

// 从T 中排除 U
type Exclude<T, U> = T extends U ? never : T;

demo

// 取 T 和 U 中,T中的差集
type T = Exclude<1 | 2, 1 | 3>// -> 2
type T0 = Exclude<"a" | "b" | "c", "a"> // ->  "b" | "c"

Extract

是提取出 T 包含在 U 中的元素, 换种更加贴近语义的说法就是从 T 中提取出 U

源码

type Extract<T, U> = T extends U ? T : never;

demo

// 类型取交集
type T0 = Extract<"a" | "b" | "c", "a" | "f">  // ->  "a"

NonNullable

去掉类型中的 null 和 undefined

源码

type NonNullable<T> = T extends null | undefined ? never : T;

demo

type T0 = NonNullable<string | number | undefined> // -> string | number

ReturnType

源码

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

Parameters

从函数类型的参数中使用的类型构造一个元组类型。

demo

declare function f1(arg: { a: number; b: string }): void;
type T3 = Parameters<typeof f1>;
//    type T3 = [arg: {
//        a: number;
//        b: string;
//    }]

ConstructorParameters

从构造函数类型的类型构造元组或数组类型。它会生成具有所有参数类型的元组类型(如果Type不是构造函数,则为 never)。

demo

type T0 = ConstructorParameters<ErrorConstructor>;
//    ^ = type T0 = [message?: string]
type T1 = ConstructorParameters<FunctionConstructor>;
//    ^ = type T1 = string[]
type T2 = ConstructorParameters<RegExpConstructor>;
//    ^ = type T2 = [pattern: string | RegExp, flags?: string]
type T3 = ConstructorParameters<any>;
//    ^ = type T3 = unknown[]

type T4 = ConstructorParameters<Function>;
Type 'Function' does not satisfy the constraint 'new (...args: any) => any'.
  Type 'Function' provides no match for the signature 'new (...args: any): any'.
//    ^ = type T4 = never

练习

  1. 力扣原题 ===》解答

社区工具类型

@zzkkui zzkkui changed the title 官方 utility-types 实现 Typescript utility-types 实现 Dec 3, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant