TypeScript 的全部 高级类型

既然官方提供的高级类型并很少,那么就把他们所有都说明一遍吧,让咱们在开发中更加效率。其中 Typescript 中的 Partial, Readonly, Record, Pick 中已经对这4个使用频率最高的进行了说明,所以这里再也不重复。html

备注:高级类型声明中,涉及到的 条件类型、映射类型、类型推断、never 类型,以前的均有分享,你能够在个人专栏里看到。(其实,以前解读的这些就是为介绍官方的高级类型作前提)typescript

这些高级类型可能你并不会用到,但简单过一遍知道 TS 预置了哪些就行,当某些开放场景想起时,总会带来惊喜。(编写这些特性的是基于 v3.8-Beta版本)c#

Required< T >

/** * Make all properties in T required */
type Required<T> = {
    [P in keyof T]-?: T[P];
};
复制代码

Partial<T> 程序类型的做用相反,将类型属性都变成必填。app

type Coord = Required<{ x: number, y?:number }>;

// 等同于
type Coord = {
	x: number;
	y: number;
}
复制代码

主要是由于 -? 映射条件的装饰符的能力,去掉了全部可选参数状态,更多的装饰符说明能够以前分享的 TypeScript 的映射类型 Mapped types (e.g. { [P in K]: T[P] })函数

Exclude<T, U>

/** * Exclude from T those types that are assignable to U */
type Exclude<T, U> = T extends U ? never : T;
复制代码

排除一个 联合类型 中指定的子类型:post

type T0 = Exclude<'a' | 'b' | 'c', 'b'> // 'a' | 'c'
type T1 = Exclude<string | number | boolean, boolean> // string | number
复制代码

主要是基于 extends 条件类型的解析推迟的特性,返回了匹配以外的全部 候选类型,配合 never 类型 的空值特性,实现了这一高级类型。ui

Extract<T, U>

/** * Extract from T those types that are assignable to U */
type Extract<T, U> = T extends U ? T : never;
复制代码

Exclude<T, U> 彻底相反的功能,用于提取指定的 联合类型,若是不存在提取类型,则返回never。能够用在判断一个复杂的 联合类型 中是否包含指定子类型:this

type T0 = Extract<'a' | 'b' | 'c', 'a'> // 'a'
type T1 = Extract<string | number | boolean, boolean> // boolean
复制代码

Omit<T, K extends keyof any>

/** * Construct a type with the properties of T except for those in type K. */
type Omit<T, K extends keyof any> = Pick<T, Exclude<keyof T, K>>;
复制代码

排除接口中指定的属性:spa

interface I1 {
	a: number;
	b: string;
	c: boolean;
}

type AC = Omit<I1, 'b'>;     // { a:number; c:boolean } 
type C = Omit<I1, 'a' |'b'>  // { c: boolean }
复制代码

这个在高级类型的使用频率也比较高。code

NonNullable< T >

/** * Exclude null and undefined from T */
type NonNullable<T> = T extends null | undefined ? never : T;
复制代码

过滤掉 联合类型 中的 nullundefined 类型:

type T1 = NonNullable<string | null | undefined>; // string
复制代码

额外说明下,由于 nullundefined 类型的特殊性,他们能够赋值给任何类型,这每每会带来意料以外的错误。当你开启 --strictNullChecks 设置后,TS 就会严格检查,只有被声明 null 后才能被赋值:

// 关闭 --strictNullChecks
let s: string = "foo";
s = null; // 正常

// 开启 --strictNullChecks
s = null; // Error: Type 'null' is not assignable to type 'string'. 
复制代码

Parameters<T extends (...args: any) => any>

/** * Obtain the parameters of a function type in a tuple */
type Parameters<T extends (...args: any) => any> = T extends (...args: infer P) => any ? P : never;
复制代码

获取函数的所有参数类型,以 元组类型 返回:

type F1 = (a: string, b: number) => void;

type F1ParamTypes = Parameters(F1);  // [string, number]
复制代码

若是你想了解原理,能够看以前分享的 TypeScript 条件类型的 infer 类型推断能力

ConstructorParameters<T extends new (...args: any) => any>

/** * Obtain the parameters of a constructor function type in a tuple */
type ConstructorParameters<T extends new (...args: any) => any> = T extends new (...args: infer P) => any ? P : never;
复制代码

同上面的类型很类似,只是这里获取的是 构造函数 的所有参数。关于构造函数声明,以及如何使用此 高级类型 的方式:

interface IEntity {
    count?: () => number
}

interface IEntityConstructor {
    new (a: boolean, b: string): IEntity;
}

class Entity implements IEntity {
    constructor(a: boolean, b: string) { }
}

type EntityConstructorParamType = ConstructorParameters<IEntityConstructor>; // [boolean, string]
复制代码

这里的 IEntityConstructor 接口用来干什么的呢,当基于 建立实例函数 时就派上了用场:

function createEntity(ctor: IEntityConstructor, ...arg: EntityConstructorParamType): IEntity {
    return new ctor(...arg);
}

const entity = createEntity(Entity, true, 'a');
复制代码

ReturnType<T extends (...args: any) => any>

/** * Obtain the return type of a function type */
type ReturnType<T extends (...args: any) => any> = T extends (...args: any) => infer R ? R : any;
复制代码

接收函数声明,返回函数的返回值类型,若是多个类型则以 联合类型 方式返回:

type F1 = () => Date;

type F1ReturnType = ReturnType<F1>; // Date
复制代码

InstanceType<T extends new (...args: any) => any>

/** * Obtain the return type of a constructor function type */
type InstanceType<T extends new (...args: any) => any> = T extends new (...args: any) => infer R ? R : any;
复制代码

获取 构造函数 的返回类型,若是是多个就以 联合类型 的方式返回,咱们借用上面的定义:

type EntityType = InstanceType<IEntityConstructor>; // IEntity
复制代码

ThisParameterType< T >

/** * Extracts the type of the 'this' parameter of a function type, or 'unknown' if the function type has no 'this' parameter. */
type ThisParameterType<T> = T extends (this: infer U, ...args: any[]) => any ? U : unknown;
复制代码

获取函数中 this 的数据类型,若是没有则返回 unknown 类型:

interface Foo {
    x: number
};

function fn(this: Foo) {}

type Test = ThisParameterType<typeof fn>; // Foo
复制代码

由于能够在 TS 声明函数的 this ,此方法用于获取此声明,具体的使用:

fn.bind({ x: 1 });   // 正常

fn.bind({ x: '1' }); // Error: ...Type 'string' is not assignable to type 'number'...
复制代码

OmitThisParameter< T >

/** * Removes the 'this' parameter from a function type. */
type OmitThisParameter<T> = unknown extends ThisParameterType<T> ? T : T extends (...args: infer A) => infer R ? (...args: A) => R : T;
复制代码

移除函数中的 this 数据类型:

interface Foo {
    x: number
};

type Fn = (this: Foo) => void

type NonReturnFn = OmitThisParameter<Fn>; // () => void
复制代码

声明此类的函数类型效果以下:

function f(this: void) {} // 此声明在函数内不可以使用 this
复制代码
相关文章
相关标签/搜索