typescript的utiltity types类型
- Partial: 将T的属性转为可选? 
- Readonly: 将T的属性转为只读 
- Record:将属性K的类型指定为T类型 
- Pick: 获取T中的部分K属性,只保留K选择的属性 
- Omit: 从T中删除定义的K属性,排除K选择的属性 
- Exclude: 从T中剔除可以赋值给U的类型 
- Extract: 提取T中可以赋值给U的类型。 
- NonNullable: 从T中剔除null和undefined。 
- Parameters: 获取函数参数类型 
- ConstructorParameters: 获取构造函数的参数类型 
- ReturnType: 获取函数返回值类型 
- InstanceType: 获取构造函数类型的实例类型。 
- Required:将T的属性转为必选! 
- ThisParameterType
- OmitThisParameter
- ThisTypePartial将T的属性转为可选?- type A = {a:number, b:string}
- type A1 = Partial<A> // { a?: number; b?: string;}
 Required将T的属性全转为必选!- type A = {a?:number, b?:string}
- type A1 = Required<A> // { a: number; b: string;}
 Pick获取T中的部分K属性,只保留K选择的属性- type A = {a:number, b:string}
- type A1 = Pick<A, 'a'> // {a:number}
 Omit排除K中选择的属性- type A = {a:number, b:string}
- type A1 = Omit<A, 'a'> // {b:string}
 Record创建一个类型,K代表键值的类型, T代表值的类型- type A1 = Record<number, string> // 等价{ [x: number]: string };
 Exclude过滤T中和U相同(或兼容)的类型- type A1 = Exclude<number|string, string|number[]> // number
- // 兼容
- type A2 = Exclude<number|string, any|number[]> // never , 因为any兼容number, 所以number被过滤掉
 Extract提取T中和U相同(或兼容)的类型- type A1 = Extract<number|string, string|number[]> // string
 NonNullable剔除T中的undefined和null- type A1 = NonNullable<number|string|null|undefined> // number|string
 ReturnType获取函数返回值类型- type A1= ReturnType<()=>number> // number
 InstanceType返回构造函数实例的类型
 ts中类有2种类型, 静态部分的类型和实例的类型, 所以T如果是构造函数类型, 那么InstanceType可以返回他的实例类型 ```typescript interface A{ a:HTMLElement; }
interface AConstructor{ new():A; }
function create (AClass:AConstructor):InstanceType
<a name="YeI3H"></a>
### Parameters<T>
获取函数参数类型,返回类型为元祖, 元素顺序同参数顺序
```typescript
interface A{
(a:number, b:string):string[];
}
type A1 = Parameters<A> // [number, string]
ConstructorParameters
 获取构造函数的参数类型
interface AConstructor{
new(a:number):string[];
}
type A1 = ConstructorParameters<AConstructor> // [number]
extends(条件类型)
T extends U ? X : Y
用来表示类型是不确定的, 如果U的类型可以表示T, 那么返回X, 否则Y
type A = string extends '123' ? string :'123' // '123'
type B = '123' extends string ? string :123 // string
infer(类型推断)
单词本身的意思是”推断”, 实际表示在extends条件语句中声明待推断的类型变量
type Parameters<T extends (...args: any) => any> = T extends (...args: infer P) => any ? P : never;
声明一个P用来表示…args可能的类型, 如果(…args: infer P)可以表示 T, 那么返回…args对应的类型, 也就是函数的参数类型, 反之返回never.
注意: 开始的T extends (…args: any) => any用来校验输入的T是否是函数, 如果不是函数ts会报错, 如果直接替换成T不会有报错, 会一直返回never.
接下来利用infer来实现”删除元祖类型中第一个元素”, 常用于简化函数参数
export type Tail<Tuple extends any[]> = ((...args: Tuple) => void) extends ((a: any, ...args: infer T) => void) ? T : never;
Omit、Pick、Exclude三者的区别
Omit< key:value,key>
- 作用:基于已经声明的类型进行属性剔除获得新类型
- 用例:- type User = {
- id: string;
- name: string;
- email: string;
- };
- type UserWithoutEmail = Omit<User, "email">;// UserWithoutEmail ={id: string;name: string;}
 
Pick< key:value,key >
- 作用:从KeyValue中挑选出部分Key对应的类型当作新类型使用(与omit相反,omit是剔除声明项,pick是挑选声明项)
- 用例: - interface Todo {
- title: string;
- description: string;
- completed: boolean;
- }
- type TodoPreview = Pick<Todo, "title" | "completed">;
- const todo: TodoPreview = {
- title: "Clean room",
- completed: false
- };
 - Exclude< T, U >
- 作用:T中取T、U交集的补集 
- 与Omit作比较:- Omit左右两个参数属于不同类型,左是一个完整的类型,包含key、value,右侧只有key
- Exclude左右两个参数属于同种类型
 
- 用例:
 |- type T0 = Exclude<"a" | "b" | "c", "a">; // "b" | "c"
- type T1 = Exclude<"a" | "b" | "c", "a" | "b">; // "c"
- type T2 = Exclude<string | number | (() => void), Function>; // string | number
 
 - 相同点:
 - 三种工具类都是使用已有的类型进行属性过滤获得新的类型
 - Omit和Exclude都是做属性剔除
 - Omit和Pick的参数类型都是<{key:value},key>
 - 不同点:
 - Exclude的参数类型没有限制,可以是字面量也可以是具体的类型如string、boolean等,而Omit和Pick的第二参数则必须是第一参数的子属性
 - Pick搭配Exclude实现Omit:Exclude先剔除不要的键名,挑出想要的键名,Pick再从键值对中根据键名挑选出来。
 实现公式:Omit=Pick>。其中:T: K:key 
 | | —- |
 
                         
                                

