• Typescript的高级tricks(in,keyof,Partial,Pick,Exclude等)


    Typescript的高级tricks

    1.in keyof

    1.1 keyof

    keyofObject.keys 略有相似,只不过 keyofinterface 的键

    interface Point {
      x: number;
      y: number;
    }
    
    // type keys = "x" | "y"
    type keys = keyof Point;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    假设有一个 object 如下所示,我们需要使用 typescript 实现一个 get 函数来获取它的属性值

    const data = {
      a: 3,
      hello: 'world'
    }
    
    function get(o: object, name: string) {
      return o[name]
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    我们刚开始可能会这么写,不过它有很多缺点

    1. 无法确认返回类型:这将损失ts 最大的类型校验功能
    2. 无法对 key做约束:可能会犯拼写错误的问题

    这时可以使用 keyof 来加强 get 函数的类型功能

    function get<T extends object, K extends keyof T>(o: T, name: K): T[K] {
      return o[name]
    }
    
    • 1
    • 2
    • 3

    1.2 in

    in 则可以遍历枚举类型,例如

    type Keys = "a" | "b"
    type Obj =  {
      [p in Keys]: any
    } // -> { a: any, b: any }
    
    • 1
    • 2
    • 3
    • 4

    keyof 产生枚举类型,,in 使用枚举类型遍历,所以他们经常一起使用,看下 Partial 源码

    type Partial<T> = { [P in keyof T]?: T[P] };
    
    • 1

    上面语句的意思是 keyof T 拿到 T 所有属性名,然后 in 进行遍历,将值赋给 P,最后 T[P] 取得相应属性的值


    2. Required& Partial& Pick

    Required 相当于全部属性都是非空的

    Partial 全部属性都是可选的

    Pick相当于选取某个接口的子keys集合

    type Required<T> = {
      [P in keyof T]-?: T[P];
    };
    
    type Partial<T> = {
      [P in keyof T]?: T[P];
    };
    
    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">
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    4. never& Exclude& Omit

    type Exclude<T, U> = T extends U ? never : T;
    
    // 相当于: type A = 'a'
    type A = Exclude<'x' | 'a', 'x' | 'y' | 'z'>
    
    • 1
    • 2
    • 3
    • 4

    结合 Exclude 可以推出 Omit 的写法

    type Omit<T, K extends keyof any> = Pick<T, Exclude<keyof T, K>>;
    
    interface User {
      id: number;
      age: number;
      name: string;
    };
    
    // 相当于: type PickUser = { age: number; name: string; }
    type OmitUser = Omit<User, "id">
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    Omit 和Exclude 的区别貌似是 Omit作用于struct,Exclude 作用于集合qwq

    5. interface & type的区别

    一般来说,interfacetype 区别很小,比如以下两种写法差不多

    interface A {
      a: number;
      b: number;
    };
    
    type B = {
      a: number;
      b: number;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    其中 interface 可以如下合并多个,而 type 只能使用 & 类进行连接

    interface A {
      a: number;
    }
    
    interface A {
      b: number;
    }
    
    const a: A = {
      a: 3,
      b: 4
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    6.参考文章

    传送门

  • 相关阅读:
    存折与信用卡(继承)Java
    华为OD刷题C卷 - 每日刷题 4
    Python表格处理模块xlrd在Anaconda中的安装
    mongodb入门(二)
    K_A02_003 基于单片机驱动8位数码管模块(MAX7219) 0-7静态显示+滚动显示
    威班11月份PMP模拟考试实录
    进销存系统和ERP系统怎么选?有什么区别?
    ElasticSearch万字入门教程 一天上手ElasticSearch
    Code For Better 谷歌开发者之声——使用TensorFlow的时间序列预测
    Selenium:Web自动化框架
  • 原文地址:https://blog.csdn.net/weixin_45750972/article/details/127710694