关键字,技巧理解
keyof, 用来获得一个对象接口的所有 key 值
interface Point {
x: number;
y: number;
}
// type keys = "x" | "y"
type keys = keyof Point;
in 则能够遍历枚举类型
type Keys = "a" | "b"
type Obj = {[p in Keys]: any
} // -> {a: any, b: any}
typeof 用来获取根本数据的类型
let p = {
name: 'zs',
age:10
}
function p1(parmas: typeof p) {// 它会去解析 p。而后变成 parmas : { name:string, age:number}
console.log(p.age)
console.log(p.name)
}
p1(p)
留神
只能用来查问变量或者属性的类型。
无奈查问其余模式的类型。比如说: 返回调用的类型。extends 条件语句
extends 可能用来继承一个 class、interface, 还可能用来判断条件类型
T extends U ? X : Y
// T U X Y 四个是占位符,别离示意四种类型;// T extends U 示意 T 类型能被赋值给 U 类型,,这里还波及到 TS 类型兼容性;// 条件类型的散发个性(再续)
infer 申明一个变量来承载 extends 条件语句中的某些待推断的类型
infer 语法的限度如下:
- infer 只能在条件类型的 extends 子句中应用
-
infer 失去的类型只能在 true 语句中应用, 即 X 中应用
type Union<T> = T extends Array<infer U> ? U: never // 泛型参数 T 满足约束条件 Array<infer U> 那么就返回这个类型变量 U
type ParamType<T> = T extends (param: infer P) => any ? P : T; // 解析如果 T 能赋值给(param: infer P) => any 类型,就返回 P,否则就返回 T interface IDog { name: string; age: number; } type Func = (dog: IDog) => void; type Param = ParamType<Func>; // IDog type TypeString = ParamType<string>; // string
is 和 asserts
ts 不会检测自定义办法的判断语句,如果须要,散发判断,就要在自定义办法里做好参数签名,不论是谓词签名 is 还是断言签名 asserts 都能够
// asserts 断言
function yell(str: any) {console.log(str); // str: any
assert(typeof str === 'string');
return str; // str: string,通过 asserts 断言
// 没有断言,这里 str 仍旧是 any
}
function assert(condition: any): asserts condition {if (!condition) {throw new Error('谬误 ====');
}
}
// is 帮忙咱们实现自定义类型判断办法的类型收窄
function isNil<T>(v: T | undefined | null): v is undefined | null {return v === undefined || v === null;}
function test(v: number | undefined | null) {if (!isNil(v)) {console.log(Math.round(v));
// 没有 is 签名
// ts 告警如下
// Argument of type 'number | null | undefined' is not assignable to parameter of type 'number'.
// Type 'undefined' is not assignable to type 'number'.ts(2345)
}
}
没有 is 签名告警
高级工具类型
-
Partial, 传入的属性变为可选项
// 源码 type Partial<T> = {[P in keyof T]?: T[P] };
// 示例 type Animal = { name: string, category: string, age: number, eat: () => number} type PartOfAnimal = Partial<Animal>; //PartOfAnimal 继承 animal 全副属性,然而全副可选
-
Required, 将传入的属性变为必选项, 与 Partial 相同
// 源码 type Required<T> = {[P in keyof T]-?: T[P] };
-
Mutable,将类型的属性「变成可批改」
// 源码 type Mutable<T> = {-readonly [P in keyof T]: T[P]; };
-
Readonly,将类型的属性「变成只读」,相同
-readonly,就是移除子属性的 readonly 标识。// 源码 type Readonly<T> = {readonly [P in keyof T]: T[P] };
-
Record,将 K 中所有的属性的值转化为 T 类型
// 源码 type Record<K extends keyof any, T> = {[P in K]: T };
// 示例 1 interface PageInfo {title: string;} type Page = "home" | "about" | "contact"; const nav: Record<Page, PageInfo> = {about: { title: "about"}, contact: {title: "contact"}, home: {title: "home"}, }; // 示例 2 type keys = 'A' | 'B' | 'C' const result: Record<keys, number> = { A: 1, B: 2, C: 3 }
// 示例 3 Record<string, string | string[]> // 相当于 interface api {[key: string]: string | string[];}
-
Pick,选择性继承,从 T 中取出 一系列 K 的属性,
// 源码 type Pick<T, K extends keyof T> = {[P in K]: T[P] };
// 示例 interface User { id: number; age: number; name: string; }; // 相当于: type PartialUser = {id?: number; age?: number; name?: string;} type PartialUser = Partial<User> // 相当于: type PickUser = {id: number; age: number;} type PickUser = Pick<User, "id" | "age">
-
Omit,疏忽继承。和 Pick 都是继承,然而 key 的获取形式相同。
// 源码 type Omit = Pick<T, Exclude<keyof T, K>> // 应用 type PickUser = Omit<User, 'name'> // 相当于: type PickUser = {id: number; age: number;}
-
Extract,提取
Exclude 的作用是提取出 T 蕴含在 U 中的元素,其实就是从 T 找出 T 和 U 的交加
// 源码 type Extract<T, U> = T extends U ? T : never;
// 示例 type T = Extract<1 | 2, 1 | 3> // -> 1
-
Exclude,排除,如果 T 是 U 的子类型的话,那么就会返回 X,否则返回 Y
Exclude 的作用是从 T 中找出 U 中没有的元素, 换种更加贴近语义的说法其实就是从 T 中排除 U
// 源码 type Exclude<T, U> = T extends U ? never : T;
interface student { name: string; addr: string; } type ExcludeKeys = Exclude<keyof User, keyof student>; // type ExcludeKeys = 'addr';
// 示例 type T = Exclude<1 | 2, 1 | 3> // -> 2
-
ReturnType,获取函数返回值
// 源码 type ReturnType<T extends (...args: any) => any> = T extends (...args: any) => infer R ? R : any;
-
NonNullable,从类型 T 中排除 null 和 undefined
// 源码 type NonNullable<T> = T extends null | undefined ? never : T;
// 示例 type Msg = string | null | number | undefined; type MsgNonNullable = NonNullable<Msg>; // 等价 type nonNullable = string | number;
Nullable 能够为 null
// 源码 declare type Nullable<T> = T | null;
// 示例 type Msg = string | number; type MsgNonNullable = Nullable<Msg>; // 等价 type nonNullable = string | number | null;
-
Parameters,获取函数的参数类型
// 源码 type Parameters<T extends (...args: any) => any> = T extends (...args: infer P) => any ? P : never;
// 示例 const updata = (a: string, b: number) => ({a, b}); type ArrType = Parameters<typeof updata> // ArrType => [a: string, b: number]
-
ConstructorParameters,获取构造函数的参数类型
和 Parameters 区别就是参数类型限度为 abstract 抽象类
// 源码 type ConstructorParameters<T extends abstract new (...args: any) => any> = T extends abstract new (...args: infer P) => any ? P : never;
-
InstanceType,获取实例类型, 通过传入的抽象类参数获取到他的实例类型
// 源码 type InstanceType<T extends abstract new (...args: any) => any> = T extends abstract new (...args: any) => infer R ? R : any;
// 示例 const updata = (a: string, b: number) => ({a, b}); type ArrType = Parameters<typeof updata> // ArrType => [a: string, b: number]
自定义工具类型
-
NonFunctionKeys,获取对象中所有非函数类型属性的 key
// 实现 type NonFunctionKeys<T extends object> = {[K in keyof T]-?: T[K] extends Function ? never : K }[keyof T]
-
NonFunction,剔除对象中的函数的新类型
// 实现 type NonFunction<T extends object> = Pick<T,NonFunctionKeys<T>>
-
AxiosReturnType,获取 axios 办法返回的 AxiosPromise<Resp> 中 Resp 类型
// 实现 import {AxiosPromise} from 'axios' type AxiosReturnType<T> = T extends (...args: any[]) => AxiosPromise<infer R> ? R : any
-
ArrayElement,提取数组成员类型
一个思路是 用 extends 限度数组类型, 而后用数组 key 类型为 number 的个性取出其属性类型
// 实现 type ArrayElement<T extends readonly unknown[]> = T[number]; type AEL = ArrayElement<[number, string]>; // number | string
第二种写法的外围思路就是用 infer 来隐射 数组的属性类型
// 实现 type ArrayElement<A> = A extends readonly (infer T)[] ? T : never