【TypeScript】类型拓展

1,615 阅读3分钟

这是我参与8月更文挑战的第25天,活动详情查看:8月更文挑战


TS类型拓展

(1)联合类型

对于一个不知道类型的变量,我们可以使用any,可以使用unknown,但使用这两种方法定义的变量,其范围太大

因此,可以使用联合类型来稍微约束下这个范围

  • 联合类型表示取值可以为多种类型中的一种

    • 使用|来分隔多种类型
    • 适用于不确定具体是什么类型,但能确定是哪几种类型的值
    // 表示形参x 可以是 number 或者 string 类型
    function func2(x: number | string): string {
        return ''
    }
    
    // 表示数组可以是多个类型
    let arr: (number | string)[] = [18, 'Ruovan', 24]
    
    

(2)类型断言

  • 类型断言和联合类型搭配使用

    当声明一个变量是联合类型时,表示变量可以有多个类型,但每个类型的变量所拥有的方法或者说属性是不一样的

    因此,需要使用类型断言来确定当前变量具体是什么变量

    • 它是联合类型中的一种,只是做类型选择,而不是做类型转换
    • 它只在编译阶段起作用
  • 类型断言的两种形式:

    • 第一种:as语法

      • 值 as 类型
      function getLength(x: number | string): number {
          // 将参数 x 作为 string 类型
          const temp = x as string
          // 判断是否有 .length 方法
          if ( temp.length ) {
              // true 表示 x 类型就是 string,有 length 属性
              return temp.length
          } else {
              // false 表示 x 的类型不是 string,是 number,
              return x
          }
      }
      
      
    • 第二种:<>语法

      • <类型>值
      function getLength(x: number | string): number {
          // 同上
          const temp = <string>x
          if ( temp.length ) {
              return temp.length
          } else {
              return x
          }
      }
      
      

(3)类型推断

  • 类型推断是在没有明确的指定类型的时候,由程序自动推测出一个符合语境的类型

  • 具体的,可以分为两种情况:

    • 一种是在定义变量时赋值了,但没有注解类型,则会被推断为值的类型

      // 1.定义变量时赋值了, 推断为 值的类型
      let number = 24
      console.log(typeof number) // number
      number = 'ruovan' // Error
      
      
    • 一种是在定义变量时没有赋值,也没有注解类型,则会被推断为any类型

      • 被推断为any类型表示可以赋值为任何类型的值
      // 2.定义变量时没有赋值, 推断为 any 类型
      let notsure
      
      notsure = 24
      console.log(typeof notsure) // number
      
      notsure = 'Ruovan'
      console.log(typeof notsure) // string
      
      
      

(4)类型守卫

  • 当遇到联合类型时,通过类型守卫,可以对变量的类型作出限制,分别对不同类型的变量作出处理

  • 可以通过一下几种方式来判断:

    • 类型判断:typeof

      // 类型判断 typeof
      function test(arg: string | boolean | number): string {
          if (typeof arg == 'string') {
              // 这里 arg 的类型限制为 string
              return arg
          } else if (typeof arg == 'number') {
              // 这里 arg 的类型限制为 number
              return arg + ''
          } else {
              // 这里 arg 的类型限制为 boolean
              return arg + ''
          }
      }
      
      
    • 实例判断:instanceof

      • (同类型判断)
    • 属性判断:in

      // 定义接口
      interface one {
          name: string;
          age: string;
      }
      interface two {
          money: number;
          sex: string;
      }
      
      function test(arg: one | two): void{
          // 属性判断
          if ("name" in arg) { 
              // 这里 arg 限制为对象 one
              console.log(arg.name)
          }
          if ("sex" in arg) {
              // 这里 arg 限制为对象 two
              console.log(arg.sex)
          }
      }
      
      

(5)类型别名

当定义一个联合类型太多时,可以使用类型别名来给一个类型定义一个别名

  • 类型别名:

    • 使用type定义
    • 语法:type 别名 = 类型
    // 定义一个别名
    type message = number | string
    
    // 使用
    let arr: message[] = [1, '2', 3]
    
    let name: message = 'Ruovan'
    let age: message = 24
    
    

(6)交叉类型

  • 交叉类型:

    • 需要同时满足多个类型,多种类型会叠加成为一种类型,变量必须要包含所有类型的特性
    • 使用&进行多个类型的叠加
    interface IPerson {
        name: string;
        age: number;
    }
    interface ISex {
        sex: string;
    }
    
     // 定义 IPeople 类型为 上面两个类型的组合
    type IPeople = IPerson & ISex
    
    // 定义的变量 必须同时满足这两个接口的类型条件
    const people: IPeople = {
        name: 'Ruvoan',
        age: 24,
        sex: 'male'
    }
    
    

本人前端小菜鸡,如有不对请谅解