关于typescript:ts-高级工具类

43次阅读

共计 4978 个字符,预计需要花费 13 分钟才能阅读完成。

关键字,技巧理解

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 语法的限度如下

  1. infer 只能在条件类型的 extends 子句中应用
  2. 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 签名告警


高级工具类型

  1. 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 全副属性,然而全副可选
  2. Required, 将传入的属性变为必选项, 与 Partial 相同

    // 源码
    type Required<T> = {[P in keyof T]-?: T[P] };
  3. Mutable,将类型的属性「变成可批改」

    // 源码
    type Mutable<T> = {-readonly [P in keyof T]: T[P];
    };
  4. Readonly,将类型的属性「变成只读」,相同
    -readonly,就是移除子属性的 readonly 标识。

    // 源码
    type Readonly<T> = {readonly [P in keyof T]: T[P] };
  5. 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[];}
  6. 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">
  7. Omit,疏忽继承。和 Pick 都是继承,然而 key 的获取形式相同。

    // 源码
    type Omit = Pick<T, Exclude<keyof T, K>>
    
    // 应用
    type PickUser = Omit<User, 'name'>
    // 相当于: type PickUser = {id: number; age: number;}
  8. Extract,提取

    Exclude 的作用是提取出 T 蕴含在 U 中的元素,其实就是从 T 找出 T 和 U 的交加

    // 源码
    type Extract<T, U> = T extends U ? T : never;
    // 示例
    type T = Extract<1 | 2, 1 | 3> // -> 1
  9. 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
  10. ReturnType,获取函数返回值

    // 源码
    type ReturnType<T extends (...args: any) => any> = T extends (...args: any) => infer R ? R : any;
  11. 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;
  12. 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]
  13. ConstructorParameters,获取构造函数的参数类型

    和 Parameters 区别就是参数类型限度为 abstract 抽象类

    // 源码
    type ConstructorParameters<T extends abstract new (...args: any) => any> = T extends abstract new (...args: infer P) => any ? P : never;
  14. 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]

自定义工具类型

  1. NonFunctionKeys,获取对象中所有非函数类型属性的 key

    // 实现
    type NonFunctionKeys<T extends object> = {[K in keyof T]-?: T[K] extends Function ? never : K }[keyof T]
  2. NonFunction,剔除对象中的函数的新类型

    // 实现
    type NonFunction<T extends object> = Pick<T,NonFunctionKeys<T>>
  3. AxiosReturnType,获取 axios 办法返回的 AxiosPromise<Resp> 中 Resp 类型

    // 实现
    import {AxiosPromise} from 'axios'
    type AxiosReturnType<T> = T extends (...args: any[]) => AxiosPromise<infer R> ? R : any
  4. 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

正文完
 0