TypeScript | 第六章:高级类型(下篇)

125 阅读3分钟

「这是我参与11月更文挑战的第15天,活动详情查看:2021最后一次更文挑战

TypeScript系列学习笔记: TypeScript | 第一章:环境搭建及基础数据类型 TypeScript | 第二章:类、接口和之间的关系 TypeScript | 第三章:函数、泛型和枚举 TypeScript | 第四章:命名空间和模块 TypeScript | 第五章:高级类型(上篇) TypeScript | 第六章:高级类型(下篇) TypeScript | 第七章:理解声明合并,以及编写声明文件 TypeScript | 第八章:配置文件说明

一、映射类型

映射类型比较像修改类型的工具函数。

infer:待推断/延迟推断,根据实际情况推断类型。

1. Readonly

// 定义: 把每个属性都变成只读 
type Readonly<T>={
	readonly (P in keyof T):T[P];  // 循环设置泛型T的属性为只读
}

type A  = {a:number, b:string}
type AA = Readonly<A>  

2. Partial

// 定义:让属性都变成可选
type Partial<T> = {
	[P in keyof T]?:T[P]
}

type A  = {a:number, b:string}
type AA = Partial<A> // { a?: number; b?: string;}

3. Required

// 定义:让属性都变成必选
type Required<T> = {
	[P in keyof T]-?:T[P]
}

type A  = {a?:number, b?:string}
type A = Required<A> // { a: number; b: string;}

4. Pick<T,K>

// 定义:只保留自己选择的属性, K代表要保留的属性键值
type Pick<T,K extends keyof T> = {
	[P in K]:T[P]
}

type A  = Pick<{a:number,b:string,c:boolean}, 'a'|'b'>
type AA = Pick<A, 'a'|'b'> //  {a:number,b:string}

5. Omit<T,K> 

// 定义: 实现排除已选的属性
type Omit<T,K extends keysof T> = Pick<T, Exclude<keyof T, K>>;

type A  = {a:number, b:string}
type AA = Omit<A, 'a'> // {b:string}

6. Record<K,T>

// 定义:Construct a type with a set of properties K of type T
type Record<K extends keyof any, T> = {
    [P in K]: T;
};

type AA = Record<string, string> // 等价{[x:string]:string}

7. Exclude<T,U>

// 定义:过滤T中和U相同(或兼容)的类型
type Exclude<T, U> = T extends U ? never : T;

type A  = {a:number, b:string} 
type AA = Exclude<number|string, string|number[]> // number

// 兼容
type A1 = Exclude<number|string, any|number[]> // never , 因为any兼容number, 所以number被过滤掉

8. Extract<T,U>

// 定义:提取T中和U相同(或兼容)的类型
type Extract<T, U> = T extends U ? T : never;

type A  = {a:number, b:string}
type AA = Extract<number|string, string|number[]> // string

9. NonNullable

// 定义:剔除T中的undefined和null
type NonNullable<T> = T extends null | undefined ? never : T;

type A = NonNullable<number|string|null|undefined> // number|string

9. ReturnType

// 定义:获取返回的返回类型
type ReturnType<T extends (...args:any)=>any> = T extends (...args:any)=>infer R?R:any

type A= ReturnType<()=>number> // number

10. InstanceType

返回T的实例类型。

ts中类有2种类型, 静态部分的类型和实例的类型, 所以T如果是构造函数类型, 那么InstanceType可以返回他的实例类型:

// 定义:获取构造函数类型的返回类型
type InstanceType<T extends new (...args: any) => any> = T extends new (...args: any) => infer R ? R : any;

interface A{
    a:HTMLElement;
}

interface AConstructor{
    new():A;
}

function create (AClass:AConstructor):InstanceType<AConstructor>{
    return new AClass();
}

11. Parameters

// 定义:获取函数参数类型,返回类型为元祖, 元素顺序与参数顺序一样.
type Parameters<T extends (...args: any) => any> = T extends (...args: infer P) => any ? P : never;

interface A{
    (a:number, b:string):string[];
}
type AA = Parameters<A> // [number, string]

12. ConstructorParameters

// 定义:获取构造函数的参数类型,T:构造函数类型
type ConstructorParameters<T extends new (...args: any) => any> = T extends new (...args: infer P) => any ? P : never;

interface MyConstructor{
    new(a:number):number[];
}
type AA = ConstructorParameters<MyConstructor> // [number]

二、 extends

// 条件类型:表示类型是不确定的,U可以表示T,则返回X,否则Y
T extends U ? X : Y 

type A = string extends 'a'?string:'a'  // 'a'不能表示string类型,输出 'a'
type B = 'a' extends string?string:'a'  // string能表示'a',输出 string

// 类型过滤: 从T过滤掉可以赋值给U的
type Diff<T,U> = T extends U?never: T;
type C = Diff<'a'|'b'|'c','b'|'e'> // type C = 'a'|'c'
// 过滤掉null,undefined
type NotNull = Diff<T,null | undefined>
type D = NotNull<string|number|null> // type D = string|number

三、总结

至此我们遍完成了对typescript高级类型的学习。