联合类型
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);