联合类型

1.Exclude<T,U>

T是联合类型。该工具类型能够从类型T中剔除所有U的类型。

源码:

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

例子:

type T = Exclude<string | undefined, null | undefined>
  =(string extends null | undefined ? never : string) | (null extends null | undefined ? never : null)
  =string | never
  =string
type T0 = Exclude<"a" | "b" | "c", "a">; // "b" | "c"
type T1 = Exclude<"a" | "b" | "c", "a" | "b">; // "c"
type T2 = Exclude<string | (() => void), Function>; // string

2.Extract<T,U>

与Exclude<T,U>互补。T是联合类型。获取指定类型。

源码:

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

例子:

type T0 = Extract<'a' | 'b' | 'c', 'a' | 'f'>; // 'a'
type T1 = Extract<string | (() => void), Function>; // () => void
type T2 = Extract<string | number, boolean>;        // never
type T = Extract<string | number, number | boolean>
       = (string extends number | boolean ? string : nerver) | (number extends number | boolean ? number : nerver)
         = never | number
       = number

3.NonNullable<T>

作用:从类型T中剔除null类型和undefined类型,并构造一个新的类型。也就是说,获取T中的非空类型。

源码:

type NonNullable<T> = T extends null | undefined ? never : T;
// 等同于使用 Exclude
type NonNullable<T> = Exclude<T, null | undefined>

例子:

type T0 = NonNullable<string | number | undefined>;// string | number
type T1 = NonNullable<string[] | null | undefined>;// string[]

4.Record<K,T>

参数K提供了对象名联合类型,类型参数T提供了对象属性的类型。

作用:生成接口类型,将K作为属性,T作为属性值

源码:

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

例子:

type K = 'x' | 'y'
type T = number
type R = Record<K, T> // {x:number; y:number}
type MenuKey = 'home' | 'about' | 'more';
interface Menu {
  label: string;
  hidden?: boolean;
}
const menus: Record<MenuKey, Menu> = {
  about: { label: '1' },
  home: { hidden: false },
  more: { label: '2', hidden: true },
};

操作接口类型

1.Pick<T,K>

T表示源对象类型,类型参数K提供了待选取的属性名类型,它必须为对象类型T中存在的属性。

作用:从已有对象类型中选取给定的属性和其属性。

源码:

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

例子:

type T = {
  a?:string;
  readonly b:number;
  c:boolean;
}
type SomeOfT = Pick<T,'a' | 'b'>
// {a?:string; readonly b:number}
interface A {
    x:number;
    y:number;
}
type T0 = Pick<A, 'x'> // {x:number}
type T1 = Pick<A, 'y'>   // { y: number }
type T2 = Pick<A, 'x' | 'y'>;  // { x: number; y: number }
type T3 = Pick<A, 'z'>; // 报错 类型'A'中不存在属性'z'

2.Omit<T,K>

参数T表示源对象类型,类型参数K提供了待剔除的属性名类型。

作用:与Pick<T,K>互补。从已有对象类型中剔除给定的属性,然后构建出一个新的对象类型,它可以为对象类型T中不存在的属性。

源码:

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

例子:

interface A {
  x: number;
  y: number;
}
 
type T0 = Omit<A, 'x'>;       // { y: number }
type T1 = Omit<A, 'y'>;       // { x: number }
type T2 = Omit<A, 'x' | 'y'>; // { }
type T3 = Omit<A, 'z'>;       // { x: number; y: number }

3.Required<T>

作品:移除了每个属性上的可选属性修饰符“?”.“–”修饰符仅作用于带有“?”和readonly修饰符的属性。编译器在移除属性a的“?”修饰符时,同时会移除属性类型中的undefined类型,但是不会移除null类型。

源码:

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

例子:

type T = {
  a?:string | undefined | null;
  readonly b:number | undefined | null;
}
type RequiredT = Required<T>
// {a:string|null;readonly b:number | undefined |null;}

4.Readonly

参数T中的所有属性变为只读属性。

源码:

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

例子:

interface A {
  x:number;
  y:number;
}
type T = Readonly<A> // {readonly x:number; readonly y:number}

5.Partial<T>

能构造一个新类型,并将实际类型参数T中所有的属性变为可选属性

源码:

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

例子:

interface A {
  x:number;
  y:number;
}
type T = Partial<A>; // {x?:number;y?:number}

函数类型

1.Parameters<T>

作用:使用函数的参数构造一个元组类型

源码:

type Parameters<T extends (...args:any) => any> = T extends (...args:infer P) => any ? P : never

例子:

type T0 = Parameters<() => string>;        // []
type T1 = Parameters<(s: string) => void>; // [string]
type T2 = Parameters<<T>(arg: T) => T>;    // [unknown]
type T4 = Parameters<
   (x: { a: number; b: string }) => void
>;                                         // [{ a: number, b: string }]
type T5 = Parameters<any>;                 // unknown[]
type T6 = Parameters<never>;               // never
type T7 = Parameters<string>;         // 编译错误!string类型不符合约束'(...args: any) => any'
type T8 = Parameters<Function>;    // 编译错误!Function类型不符合约束'(...args: any) => any'

2.ConstructorParameters<T>

作用:获取构造函数T中的参数类型,并使用参数类型构造一个元组类型。若类型T不是函数类型,则返回never类型。需要使用infer关键字去推断构造参数的类型。

源码:

type ConstructorParameters<T extends abstract new (...args: any) => any> 
    = T extends abstract new (...args: infer P) => any ? P : never;

例子:

type T0 = ConstructorParameters<new (x: string, y: number) => object>; // [string, number]
type T1 = ConstructorParameters<new (x?: string) => object>; // [(string | undefined)?]
type T2 = ConstructorParameters<string>;   // 编译错误
type T3 = ConstructorParameters<Function>; // 编译错误

3.ReturnType<T>

作用:获取函数类型T的返回值类型。

源码:

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

例子:

type T0 = ReturnType<() => string>; // string
type T1 = ReturnType<() => { a: string; b: number }>; // { a: string; b: number }
type T2 = ReturnType<(s: string) => void>; // void
type T3 = ReturnType<<T>() => T>; // {}
type T4 = ReturnType<<T extends U, U extends number[]>() => T>;// number[]
type T5 = ReturnType<never>; // any 
type T6 = ReturnType<boolean>;   // 编译错误
type T7 = ReturnType<Function>;  // 编译错误

4.InstanceType<T>

本身则通过判断 T 是否是构造函数类型来确定返回的类型。如果是构造函数,使用 infer 可以自动推断出 R 的类型,即实例类型;否则返回的是 any 类型。

作用:获取构造函数的返回值类型,即示例类型。

源码:

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

例子:

class C {
    x = 0;
}
type T0 = InstanceType<typeof C>;         // C
type T1 = InstanceType<new () => object>; // object
type T2 = InstanceType<any>;              // any
type T3 = InstanceType<never>;            // any
type T4 = InstanceType<string>;           // 编译错误
type T5 = InstanceType<Function>;         // 编译错误

5.ThisParameterType<T>

作用:获取函数类型T中this参数的类型,若函数类型中没有定义this参数,则返回unknown类型。在使用“ThisParameterType<T>”工具类型时需要启用“--strict-FunctionTypes”编译选项。

源码:

type ThisParameterType<T> = T extends (this: infer U, ...args: any[]) => any ? U : unknown;

例子:

/**
 * --strictFunctionTypes=true
*/
function f0(this: object, x: number) {}
function f1(x: number) {}
type T0 = ThisParameterType<typeof f0>;  // object
type T1 = ThisParameterType<typeof f1>;  // unknown
type T2 = ThisParameterType<string>;     // unknown
type T = ThisParameterType<(this: Number, x: number) => void>; // Number

6.OmitThisParameter<T>

如果传入的函数类型没有显式声明 this 类型,那么返回的仍是原来的函数类型。

作用:从类型T中剔除this参数类型,并构造一个新类型。在使用“OmitThisParameter<T>”工具类型时需要启用“--strictFunctionTypes”编译选项。

源码:

type OmitThisParameter<T> = unknown extends ThisParameterType<T> ? T 
    : T extends (...args: infer A) => infer R ? (...args: A) => R : T;

例子:

/**
* --strictFunctionTypes=true
*/

function f0(this: object, x: number) {}
function f1(x: number) {}
type T0 = OmitThisParameter<typeof f0>; // (x: number) => void
type T1 = OmitThisParameter<typeof f1>; // (x: number) => void
type T2 = OmitThisParameter<string>; // string

7.ThisType<T>

在使用“ThisType<T>”工具类型时需要启用“--noImplicitThis”编译选项

作用:ThisType 的作用是可以在对象字面量中指定 this 的类型。ThisType 不返回转换后的类型,而是通过 ThisType 的泛型参数指定 this 的类型。

源码:

interface ThisType<T> { }

例子:

// 只是提供了一个空的泛型接口
interface ThisType<T> { }
// 例子
type ObjectDescriptor<D, M> = {
  data?: D;
  methods?: M & ThisType<D & M>; // methods 中 this 的类型是 D & M
};

function makeObject<D, M>(desc: ObjectDescriptor<D, M>): D & M {
  let data: object = desc.data || {};
  let methods: object = desc.methods || {};
  return { ...data, ...methods } as D & M;
}

const obj = makeObject({
  data: { x: 0, y: 0 },
  methods: {
    moveBy(dx: number, dy: number) {
            // this 类型为 D & M,在上下文中指代 { x: number, y: number } & { moveBy(dx: number, dy: number): void }。
      this.x += dx; // this => D & M
      this.y += dy; // this => D & M
    },
  },
});
obj.x = 10;
obj.y = 20;
obj.moveBy(5, 5);