TS 工具泛型

165 阅读3分钟

内置类型定义

Record

用来生成一个属性为 K,类型为 T 的类型集合

type Record<K extends keyof any, T> = {
    [P in K]: T;
}
type Foo = Record<'a', string>
interface Foo {
    a: string
}
interface Foo {
    a: string
}
interface Bar {
    b: string
}
type Baz = Record<keyof Foo | keyof Bar, number>
interface Baz {
    a: number
    b: number
}

Partial

将 T 中的所有的属性都变成可选的

type Partial<T> = {
    [P in keyof T]?: T[P];
};
interface IFoo {
    a: number
    b: number
}
type Foo = Partial<IFoo>;
interface Foo {
    a?: number
    b?: number
}

Required

作用正好和上面的Partial相反,是将 T 中的所有属性都变成必选的状态

type Required<T> = {
    [P in keyof T]-?: T[P];
};
interface IFoo {
    a?: number
    b?: number
}
type Foo = Required<IFoo>;
interface Foo {
    a: number
    b: number
}

Readonly

字面意思就可以理解是将一个类型的所有成员变为只读的状态

type Readonly<T> = {
    readonly [P in keyof T]: T[P];
};
interface IFoo {
    name: string
    age: number
}
type Foo = Readonly<IFoo>;
interface Foo {
    readonly a: number
    readonly b: number
}
const foo: Readonly<IFoo> = {
  name: 'cxc',
  age: 22,
}
foo.name = 'aa' // 错误,因为 name 仅是只读的

Pick

作用是从 T 中将所有的 K 取出来,并生成一个新的类型

type Pick<T, K extends keyof T> = {
    [P in K]: T[P];
};
interface IFoo {
     a: number
     b: number
}
type Foo = Pick<IFoo, 'a'>;
interface Foo {
    a: number
}

Exclude ~

作用是从 T 中排除掉所有包含的 U 属性

type Exclude<T, U> = T extends U ? never : T;
type TFoo = Exclude<1 | 2, 1 | 3>
type TFoo = 2; 排除掉 13, 实际上只做了排除 1, 结果是剩下了 2

Extract ~

作用正好和上面的Exclude相反, 从 T 中提取出所有包含的 U 属性值

type Extract<T, U> = T extends U ? T : never;
type TFoo = Extract<1 | 2, 1 | 3>
type TFoo = 1;

NonNullable ~

作用是去除 T 中包含的null或者undefined

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

Parameters ~

作用是用来获取一个函数的参数类型,而且返回的是只能包含一组类型的数组

type Parameters<T extends (...args: any[]) => any> = T extends (...args: infer P) => any ? P : never;
type Func = (user: string) => void
type Param = Parameters<Func> = [string];

ConstructorParameters ~

作用是用来获取一个类的构造函数参数类型,并以数组的形式返回

type ConstructorParameters<T extends new (...args: any[]) => any> = T extends new (...args: infer P) => any ? P : never;
class TFoo {
    constructor(x: string, y: number){
        console.log(x, y)
    }
}
type Foo = ConstructorParameters<typeof TFoo> = [string, number]

ReturnType ~

用来得到一个函数的返回值类型

type ReturnType<T extends (...args: any[]) => any> = T extends (...args: any[]) => infer R ? R : any;
type Func = (value: number) => string
type Fun = ReturnType<Func> = string

InstanceType

作用是获取一个类的实例类型,可以用获取到的实例类型来约束一个变量的赋值必须和类的成员类型完全一样才可以

type InstanceType<T extends new (...args: any[]) => any> = T extends new (...args: any[]) => infer R ? R : any;
class TFoo {
    public x = '1'
    public y = 2
    public say = (value: string) => {
        console.log(value)
    }
}
type Foo = InstanceType<typeof TFoo>
interface Foo {
    x: string;
    y: number;
    say: (value: string) => void;
}

Omit

Omit用来忽略 T 中的 K 属性

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

非内置类型定义(持续跟更新...)

DeepReadonly

用来深度遍历 T,并将其所有属性变成只读类型

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

ConvertNumberToString

ConvertNumberToString用来将number转换为string类型

type ConvertNumberToString<T> = {
    [K in keyof T]: T[K] extends string ? string : T[K]
}

ValueOf

ValueOfkeyof相对应。取出指定类型的所有 value

type ValueOf<T> = T[keyof T]

Mutable

用来将所有属性的readonly移除

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