zoukankan      html  css  js  c++  java
  • 深入理解TypeScript——文档篇之枚举

    一、概念

    使用枚举我们可以定义一些带名字的常量。
    我理解的是使用枚举,可以解决我们在项目中定义常量不规范的问题。

    1. 数字枚举

      // 使用初始化器
      enum Direction { // 定义数字枚举
          Up = 1, // 使用初始化器,初始值1
          Down, // 2
          Left, // 3
          Right // 4
          // ...定义依次递增
      }
      
      // 不使用初始化器
      enum Direction {
          Up, // 0
          Down, // 1
          Left,
          Right,
      }
      

      通过枚举的属性来访问枚举成员,和枚举的名字来访问枚举类型

      enum Response {
          No = 0,
          Yes = 1,
      }
      
      function respond(recipient: string, message: Response): void {
          console.log(recipient + ' ' +  message);
      }
      
      respond("Princess Caroline", Response.Yes) // Princess Caroline 1
      respond("Princess Caroline", 1000) // Princess Caroline 1000 这里值没有在Response里定义也不报错
      respond("Princess Caroline", 'df') // error 类型“"df"”的参数不能赋给类型“Response”的参数。ts(2345)
      

      数字枚举中使用函数计算得出的常量成员,后面紧跟着的常量成员必须使用常量进行初始化。

      function getSomeValue(): number {
        return 123
      }
      
      enum E {
        A = getSomeValue(),
        B = 1, // error! 前面的'A'不是常量初始化的,所以'B'需要一个初始化器
        C // 2 no error
      }
      
    2. 字符串枚举

      在一个字符串枚举里,每个成员都必须用字符串字面量,或另外一个字符串枚举成员进行初始化。

      enum Direction {
          Up = "UP",
          Down = "DOWN",
          Left = "LEFT",
          Right = "RIGHT",
      }
      
    3. 异构枚举

      enum BooleanLikeHeterogeneousEnum { // 不建议这样使用
          No = 0,
          Yes = "YES",
      }
      
    4. 计算的成员和常量成员

    • 它是枚举的第一个成员且没有初始化器,这种情况下它被赋予值 0

      // E.X is constant:
      enum E { 
          X // 0
      }
      
    • 它不带有初始化器且它之前的枚举成员是一个 数字常量。 这种情况下,当前枚举成员的值为它上一个枚举成员的值加1。

      enum E2 {
          A = 1, 
          B, // 2
          C // 3
      }
      
    • 枚举成员使用 常量枚举表达式初始化。
      使用规则:
      一个枚举表达式字面量(主要是字符串字面量或数字字面量)
      一个对之前定义的常量枚举成员的引用(可以是在不同的枚举类型中定义的)
      带括号的常量枚举表达式
      一元运算符 +, -, ~其中之一应用在了常量枚举表达式
      常量枚举表达式做为二元运算符 +, -, *, /, %, <<, >>, >>>, &, |, ^的操作对象
      若常数枚举表达式求值后为 NaN或 Infinity,则会在编译阶段报错。

      enum FileAccess {
          // constant members
          None,
          Read    = 1 << 1,
          Write   = 1 << 2,
          ReadWrite  = Read | Write,
          // computed member
          G = "123".length
      }
      
    1. 枚举成员成为类型

      enum ShapeKind {
        Circle,
        Square,
      }
      
      interface Circle {
        kind: ShapeKind.Circle;
        radius: number;
      }
      
      interface Square {
        kind: ShapeKind.Square;
        sideLength: number;
      }
      
      let c: Circle = {
        kind: ShapeKind.Square, // Error!
        // kind: 1, no error 
        // kind: 123, no error
        // kind: 'str', // 不能将类型“string”分配给类型“ShapeKind.Circle”。
        radius: 100,
      }
      

      短路问题

      enum E {
          Foo,
          Bar
      }
      
      function f(x: E) {
          if (x !== E.Foo || x !== E.Bar) { // 判断无意义,总是会通过第一个判断
              //             ~~~~~~~~~~~
              // Error! Operator '!==' cannot be applied to types 'E.Foo' and 'E.Bar'.
              console.log(x);
          }
      }
      
    2. 将枚举当作参数传入函数中

      枚举对象

      enum E {
        X, Y, Z
      }
      
      function f(obj: { X: number }) {
        return obj.X; // Works, since 'E' has a property named 'X' which is a number.
      }
      
      console.log(f(E)); // 0
      

      反向映射:从枚举值到枚举名字。

      enum Enum {
          A
      }
      let a = Enum.A;
      let nameOfA = Enum[a]; // "A"
      

      生成的代码中,枚举类型被编译成一个对象,它包含了正向映射( name -> value)和反向映射( value -> name)。 引用枚举成员总会生成为对属性访问并且永远也不会内联代码。

      要注意的是 不会为字符串枚举成员生成反向映射。

    3. const枚举
      减少重复代码定义产生的代码量开销
      避免非直接的对枚举成员的访问

      const enum Enum {
          A = 1,
          B = A * 2
      }
      

      常量枚举只能使用常量枚举表达式,并且不同于常规的枚举,它们在编译阶段会被删除。
      常量枚举成员在使用的地方会被内联进来。
      常量枚举不允许包含计算成员。

      // 使用常量枚举
      const enum Directions {
          Up,
          Down,
          Left,
          Right
      }
      
      let directions = [Directions.Up, Directions.Down, Directions.Left, Directions.Right] // [0 /* Up */, 1 /* Down */, 2 /* Left */, 3 /* Right */]
      
      // 使用计算初始化枚举成员
      function getval() {
        return 123
      }
      
      enum Directions {
          Up = getval(),
          Down = 1
      }
      
      let directions = [Directions.Up, Directions.Down] // [123, 1]
      
    4. 外部枚举

      外部枚举用来描述已经存在的枚举类型的形状。

      declare enum Enum { // 没有完全弄懂这个declare,据网上博文描述,
          A = 1,
          B,
          C = 2
      }
      

      外部枚举和非外部枚举之间有一个重要的区别,在正常的枚举里,没有初始化方法的成员被当成常数成员。 对于非常数的外部枚举而言,没有初始化方法时被当做需要经过计算的。

  • 相关阅读:
    MySQL 数据恢复
    由 go orm 引发的探索
    beego 优雅重启
    2020年8月20日
    Linux 递归获取目录下所有满足条件的文件
    NET Core Kestrel部署HTTPS 一个服务器绑一个证书 一个服务器绑多个证书
    Flutter环境配置-windows
    Vue获取钉钉免登陆授权码(vue中的回调函数实践)
    【C#上位机必看】你们要的Iot物联网项目来了
    Windows Server系统部署MySQL数据库
  • 原文地址:https://www.cnblogs.com/hackftz/p/13811804.html
Copyright © 2011-2022 走看看