• TypeScript学习笔记十二:条件类型、内置条件类型



    提示:以下是本篇文章正文内容,下面案例可供参考

    一、TS中条件类型是什么?

    TS中的条件类型就是在类型中添加条件分支,以支持更加灵活的泛型,满足更多的使用场景。内置条件类型是TS内部封装好的一些类型处理,使用起来更加便利。

    二、条件类型

    1.在类型中添加条件分支

    代码如下(示例):

    namespace a {
      interface Fish {
        name1: string
      }
      interface Water {
        name2: string
      }
      interface Bird {
        name3: string
      }
      interface Sky {
        name4: string
      }
    
      // 1.在类型中添加条件分支,以支持更加灵活的泛型
      type Condition<T> = T extends Fish ? Water : Sky;
      let con1: Condition<Bird> = { name4: '天空' };
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    2.条件类型的分发

    namespace a {
      interface Fish {
        name1: string
      }
      interface Water {
        name2: string
      }
      interface Bird {
        name3: string
      }
      interface Sky {
        name4: string
      }
      // 2.条件类型的分发
      // 因为是联合类型因此会返回Water和Sky两种类型
      let con2: Condition<Fish | Bird> = { name2: '' };
      let con3: Condition<Fish | Bird> = { name4: '' };
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    3.分布式的条件分发

    namespace b {
      interface Fish {
        name1: string
      }
      interface Water {
        name2: string
      }
      interface Bird {
        name3: string
      }
      interface Sky {
        name4: string
      }
      // 分布式的条件分发
      // 找出不包含Fish的部分,下面这三种写法都可以
      type Condition<T> = [T] extends [Fish] ? Water : Sky;
      // type Condition = T[] extends Fish[] ? Water : Sky;
      // type Condition = {t: T} extends {t: Fish} ? Water : Sky;
    
      // 条件类型的分发
      // 因为是联合类型找到不包含Fish的部分,因此返回的还是Sky
      let con2: Condition<Fish | Bird> = { name4: '' };
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    4.更多示例

    namespace c {
      // 找出T中不包含U的部分
      type Diff<T, U> = T extends U ? never : T;
      type R1 = Diff<'a' | 'b' | 'c' | 'd', 'a' | 'b' | 'c'>; // R1: 'd'
      // 由于U中的'a','b','c'都是T中的子类型,因此R1的类型就是'd'
    
      // 找出T中包含U的部分
      type Filter<T, U> = T extends U ? T : never;
      type R2 = Filter<'a' | 'b' | 'c' | 'd', 'a' | 'b' | 'c'>; // R2: 'a' | 'b' | 'c'
      // 由于U中的'a','b','c'都是T中的子类型,因此R2的类型就是'a' | 'b' | 'c'
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    三、内置条件类型

    1.Exclude

    • 从T中排除掉U,和上面的Diff相同
    type Exclude<T, U> = T extends U ? never : T;
    type R3 = Exclude<'a' | 'b' | 'c' | 'd', 'a' | 'b' | 'c'>; // R3: 'd'
    
    • 1
    • 2

    2.Extract

    • 从T中找出包含U的部分,和上面的filter相同
    type Extract<T, U> = T extends U ? T : never;
    type R4 = Extract<'a' | 'b' | 'c' | 'd', 'a' | 'b' | 'c'>; // R4: 'a' | 'b' | 'c'
    
    • 1
    • 2

    3.NonNullable

    • 从T中找出不为null和undefined的参数
    type NonNullable<T> = T extends null | undefined ? never : T;
    type R5 = NonNullable<'a' | null | undefined | 'd'>; // R5: 'a' | 'd'
    
    • 1
    • 2

    4.ReturnType 和 Parameters

    • infer:推断的意思,是一个关键字
    • ReturnType 获取函数的返回类型
    • Parameters 获取函数参数类型,返回一个元组
    namespace d {
      // 1.1
      // ReturnType 获取函数的返回类型
      type ReturnType<T> = T extends (...args: any[]) => infer R ? R : T;
      function getUser() {
        return {
          name: '张三',
          age: 10
        }
      }
      // TS可以从参数中推断返回值类型
      type ReturnUser = ReturnType<typeof getUser>; // type ReturnUser = {name: string;age: number;}
    
      // 1.2
      // Parameters 获取函数参数类型,返回一个元组
      type Parameters<T> = T extends (...args: infer P) => any ? P : never;
      function getPerson(a: string, b: number) {
        return {
          name: '李四',
          age: 18
        }
      }
      type ParamsType = Parameters<typeof getPerson>; // type ParamsType = [a: string, b: number]
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    5.InstanceType 和 ConstructorParameters

    • InstanceType 获取构造函数的实例类型
    • ConstructorParameters 获取类的构造函数的参数类型
    namespace e {
      class Person {
        name: string;
        constructor(name: string) {
          this.name = name;
        }
        getName() {
          console.log(this.name);
        }
      }
    
      // ConstructorParameters 获取类的构造函数的参数类型
      type ConstructorParameters<T extends abstract new (...args: any) => any> = T extends abstract new (
        ...args: infer P) => any ? P : never;
      type Params = ConstructorParameters<typeof Person> // type Params = [name: string]
    
      // InstanceType 获取构造函数的实例类型
      type Instance = InstanceType<typeof Person>;
      let instance: Instance = {
        name: '张三',
        getName() {}
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    四、拓展infer的使用

    • 示例如下:

    1.tuple转union

    • 元组转为联合类型
    type ElementOf<T> = T extends Array<infer P> ? P : never;
    type Tuple = [string, number];
    type TupleToUnion = ElementOf<Tuple>; // type TupleToUnion = string | number
    
    • 1
    • 2
    • 3

    2,联合类型转成交叉类型

    • string | number =》string & number
    type T1 = { name: string };
    type T2 = { age: number };
    type ToIntersection<T> = T extends { a: (x: infer U) => void, b: (x: infer U) => void } ? U : never;
    // 由于U需要同时满足T1的定义、T2的定义,因此U需要包含T1、T2所有的类型,因此T3就是T1 & T2
    type T3 = ToIntersection<{ a: (x: T1) => void, b: (x: T2) => void }>; // type T3 = T1 & T2
    
    • 1
    • 2
    • 3
    • 4
    • 5

    总结

    该篇文章主要记录TS中条件类型的简单使用。下次再见。

  • 相关阅读:
    【SpringCloud】设置接口同时支持返回多种数据类型(json、xml)
    极简7照训练法,奇趣相机引领儿童AI摄影潮流
    ttkefu在线客服:高效、专业、实时服务的典范
    Map集合之HashMap细说
    Spring Boot Event Bus用法
    『忘了再学』Shell基础 — 23、其他环境变量配置文件
    Hadoop环境快速搭建(伪分布式和完全分布式步骤版)
    java for循环语句
    第6/100天 阅读笔记
    Oracle数据库学习,(一)
  • 原文地址:https://blog.csdn.net/to_the_Future/article/details/126795607