TypeScript 入门 09 - 枚举类型

361 阅读3分钟

枚举类型

详解 7 种常见枚举类型的用法

  • 可以使用枚举定义包含被命名的常量的集合

    • TS支持数字、字符两种常量值的枚举类型

      type NumTypes = 0 | 1 | 5 | 17
      type Days = "Monday" | "Sunday" | "Friday"
      
  • 可以使用 enum 关键字定义枚举类型

    • 格式是 enum + 枚举名字 + {}

      enum Days {
      	SUNDAY,
      	MONDAY,
      	TUESDAY,
      	WEDNESDAY,
      	THURSDAY,
      	FRIDAY,
      	SATURDAY
      }
      

      Days 既可以表示集合,也可以表示集合的类型。

      JS 中并没有与枚举类型对应的原始实现,TS转译器会把枚举类型转译为一个属性为常量、命名值从0开始递增数字映射的对象。

  • 通过“枚举名字.常量名字”的格式获取枚举集合里的成员

    • 既可以把枚举成员 Day.SUNDAY 作为work函数的入参,也可以把数字字面量0作为work函数的入参:

      work(Day.SUNDAY)
      work(0)
      
7种常见的枚举类型
  • 数字类型

    • 在仅仅指定常量命名的情况下,定义的就是一个默认从0开始递增的数字集合

    • 通过 “常量命名 = 数值” 的格式显示指定枚举成员的初始值

      enum Days {
      	SUNDAY = 2,  // 从2开始递增。负数、小数等,递增 + 1
      	MONDAY,
      	TUESDAY,
      	WEDNESDAY,
      	THURSDAY,
      	FRIDAY,
      	SATURDAY
      }
      

      给最后一个常量指定数值,可能会导致与上面冲突。

    • 常量命名、结构顺序都一致的两个枚举,在TS中,它们不相同、不满足恒等

      enum MyDays {
      	SUNDAY,
      	// ...
      }
      
      // MyDays 与 Days 不相同
      

      不仅仅是数字类型枚举,所有其他枚举都仅和自身兼容。

  • 字符串类型

    • 将定义值是字符串字面量的枚举

      enum Days {
      	SUNDAY = "SUNDAY",  
      	MONDAY = "MONDAY",
      	// ...
      }
      
  • 异构类型

    • TS支持枚举类型同时拥有数字和字符类型的成员

      enum Days {
      	SUNDAY = "SUNDAY",  
      	MONDAY = 2,
      	// ...
      }
      
  • 常量成员和计算(值)成员

    • 枚举成员的值既可以是数字、字符串这样的常量,也可以是通过表达式所计算出来的值

    • 常量成员:

      • 引用来自预先定义的常量成员,比如来自当前枚举或其他枚举

      • 圆括弧()包裹的常量枚举表达式

      • 在常量枚举表达式上应用的一元操作符 + - ~

      • 操作常量枚举表达式的二元操作符: + - * / % << >> 等

        只需记住缺省值(从0递增)、数字字面量、字符串字面量肯定是常量成员

  • 枚举成员类型和联合枚举

    • 联合类型使得 TS 可以更清楚地枚举集合里的确切值

    • 字面量类型所具有的类型推断、类型缩小的特性,也同样适用于字面量枚举类型

      let SUNDAY = Day.SUNDAY  // 类型是 Day
      let SUNDAY2 = Day.SUNDAY // 类型是 Day.SUNDAY
      const work = (x: Day) => {
      	if (x === Day.SUNDAY) {
      		x	// 类型缩小为Day.SUNDAY
      	}
      }
      
  • 常量枚举

    • 可以通过添加 const 修饰符定义常量枚举
    • 常量枚举定义转译为 JS 之后会被移除,并在使用常量枚举成员的地方被替换为相应的内联值
    • 因此常量枚举的成员都必须是常量成员(字面量 + 转译阶段可计算值的表达式)
  • 外部枚举

    • 可以通过 declare 描述一个在其他地方已经定义过的变量

      declare let $: any
      $('#id').addClass('show')
      
      • 在外部枚举中,如果没有指定初始值的成员都被当做计算(值)成员,这跟常规枚举恰好相反
      • 即便外部枚举只包含字面量成员,这些成员的类型也不会是字面量成员类型,自然完全不具备字面量类型的各种特性。
    • 可以一起使用 declare 和 const 定义外部常量枚举;在抹除枚举定义的同时,可以使用内联枚举值替换对枚举成员的引用。