好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

关于typescript中的枚举你需要知道这些

数字枚举

数字枚举,即枚举里所有属性的值都是数字类型,先看这段代码:

 enum   Colors {
  Red,
  Blue,
  Yellow
}

console.log(Colors.Red)   //   0 
console.log(Colors.Blue)  //   1 
console.log(Colors.Yellow)  //   2 

 

之前也提到过,当枚举里的属性没指定具体值时,默认值是从 0 开始依次排列,你也可以自己指定具体值,剩下的也是依次递增:

 enum   Colors {
  Red,
  Blue  =  5  ,
  Yellow
}

console.log(Colors.Red)   //   0 
console.log(Colors.Blue)  //   5 
console.log(Colors.Yellow)  //   6 

 

另外,数字枚举在定义值的时候,可以是 常量 或者是 计算出来的。当满足以下条件时,枚举成员可以看作常量:

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

 enum   Colors {
  Red
} 

 

2. 它未初始化器且它之前的枚举成员是一个  数字 常量。 这种情况下,当前枚举成员的值为它上一个枚举成员的值加1。

 enum   List1 { X, Y, Z }

  enum  List2 { A =  1  , B, C }

  //   List1中没初始化,X满足第一个条件,是常量 0,Y 和 Z 没初始化且之前的成员是 数字常量,所以List1所有成员都是常量

  //   List2 中A直接指定为常量 1,B,C 递增为2,3,List2中也都是常量 

 

3. 枚举成员使用  常量枚举表达式 初始化。当一个表达式满足下面条件之一时,它就是一个常量枚举表达式:

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

 

所有其它情况的枚举成员被当作是需要计算得出的值。例如:

 const  getValue = () =>  {
    return   0  
}

  enum   List {
  A  =  getValue(),
  B  =  2 ,   //   此处必须要初始化值,不然编译不通过 
   C
}

console.log(List.A)   //   0 
console.log(List.B)  //   2 
console.log(List.C)  //   3 

A的值是被计算出来的。注意注释部分,如果某个属性的值是计算出来的,那么它后面一位的成员必须要初始化值。

 

反向映射

我们可以通过 Enum[key] 或者 Enum.key 的方式获取到对应的值。typescript 还支持反向映射,即可以通过值来获取键,不过反向映射只支持数字枚举。下面是个例子:

 enum   Status {
  Success  =  200  ,
  NotFound  =  404  ,
  Error  =  500  
}

console.log(Status.Success)   //   200 
console.log(Status[ 200 ])  //   Success 
console.log(Status[Status.Success])  //   Success 

 

字符串枚举

字符串枚举值要求每个字段的值都必须是字符串字面量,或者是另外一个字符串枚举成员,如下:

 enum   Str {
  Str1  =  '  this is string one  '  ,
  Str2  =  '  this is string two  '  ,
  Str3  = Str1   //   这里引用了Str1的值 
 }

console.log(Str.Str1)   //   this is string one 
console.log(Str.Str2)  //   this is string two 
console.log(Str.Str3)  //   this is string one 

 

异构枚举

异构枚举是指,枚举可以混合字符串和数字成员,如:

 enum   Enum {
  A  =  0  ,
  B  =  '  hello  '  
}

console.log(Enum.A)   //   0 
console.log(Enum.B)  //   hello 

这种混合值类型的枚举通常是不需要的,不建议使用。因为往往我们将一类值整理为一个枚举时,它们的特点都是相似的。比如我们在做接口请求时的返回状态码,如果是状态码都是数值,如果是提示信息,都是字符串。

 

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

如果一个枚举里所有成员的值都是字面量类型的值,那么这个枚举的每个成员和枚举本身都可以作为类型来使用。字面量枚举成员需满足以下条件:

不带初始值的枚举成员,例如 enum E { A } 值为字符串字面量,例如 enum E { A = 'hello' } 值为数字字面量,或者带有一元  -  符号的数字字面量,例如 enum E { A = 1 },enum E { A = -1 }

 

(1)枚举成员类型

把符合条件的枚举成员作为类型来使用,例子:

 enum   ShapeKind {
  Circle,
  Square
}

  interface   Circle {
  kind: ShapeKind.Circle   //   使用 ShapeKind.Circle 作为类型,指定接口须有 kind 字段,且类型为 ShapeKind.Circle 
   radius: number
}

  interface   Square {
  kind: ShapeKind.Square   //   同上 
   sideLength: number
}

let c: Circle  =  {
  kind: ShapeKind.Square,   //   Error! 因为接口 Circle 的 kind 被指定为 ShapeKind.Circle类型,所以这里会报错 
  radius:  100  
} 

interface是定义接口,现在简单了解即可。

 

(2)联合枚举类型

符合条件的枚举本身可以看作是一个包含所有成员的联合类型,下面例子:

 //   枚举 Status 里有两个状态 
 enum   Status {
  Off,
  On
}

  //   枚举 Animal 里有两个动物 
 enum   Animal {
  Cat,
  Dog
}

  //   接口 Light 中定义 status字段,它是 Status 类型,可以是 Off 或者 On 状态 
 interface   Light {
  status: Status
}

let lg1: Light  =  {
  status: Status.Off   //   正确 
 }

let lg2: Light  =  {
  status: Animal.Cat   //   error 不能将类型 Animal.Cat 分配给类型 Status 
}

 

运行时的枚举

枚举是在运行时真正存在的对象,可以把枚举当作对象使用:

 enum   E {
  A,
  B
}

function func(obj: { A: number }): number {
    return   obj.A
}

console.log(func(E))   //   0 

代码中,声明了一个函数 func,它的参数是一个对象,且必须包含属性名为 A 的属性,A 的值为数值类型。当调用函数 func 时,把枚举 E 当作符合条件的实参传入,正确运行。

 

const enum

定义的枚举,在经过编译器编译后是一个对象,这个对象我们可以在程序运行时使用,前面有说到。但有时定义枚举可能只是为了让程序可读性更好,而不需要编译后的代码,即不需要编译成对象。typescript中考虑到这种情况,所以加入了 const enum (完全嵌入的枚举)。typescript官网有一个在线编译器,来看看下面的例子:

 enum   Status{
    Off,
    On
}

  const   enum   Animal{
    Dog,
    Cat
}

  const  status =  Status.On
  const  animal = Animal.Dog

这段代码编译成JavaScript后是这样的:

 var   Status;
(function (Status) {
    Status[Status[  "  Off  " ] =  0 ] =  "  Off  "  ;
    Status[Status[  "  On  " ] =  1 ] =  "  On  "  ;
})(Status  || (Status =  {}));
  var  status =  Status.On;
  var  animal =  0   /*   Dog   */ ;

可以看到编译后的代码中并没有像创建Status一样创建了Animal,而是直接把 Animal 中 Dog 值 0 替换到表达式中 Animal.Dog 的位置,这样就节省了生成代码的开销。

查看更多关于关于typescript中的枚举你需要知道这些的详细内容...

  阅读:54次