enum

71 阅读1分钟

enum

enum Fruit { Apple, Pear }

console.log(Fruit.Apple)
console.log(Fruit[0])

通过 tsc --outFile xxx.js xxx.tsJS 之后:

var Fruit;
(function (Fruit) {
    Fruit[Fruit["Apple"] = 0] = "Apple";
    Fruit[Fruit["Pear"] = 1] = "Pear";
})(Fruit || (Fruit = {}));
console.log(Fruit.Apple);
console.log(Fruit[0]);

上述代码可以理解为一个 table

Fruit[Fruit["Apple"] = 0] = "Apple"; 
// equals
Fruit["Apple"] = 0
Fruit[0] = "Apple"

所以 Fruit.Apple === 0Fruit[0] == 'Apple'

思考:

enum Enum {
  A,
}

let a = Enum.A;
let nameOfA = Enum[a]; // ?

keyof typeof

enum LogLevel {
  ERROR,
  WARN,
  INFO,
  DEBUG,
}

/**
 * This is equivalent to:
 * type LogLevelStrings = 'ERROR' | 'WARN' | 'INFO' | 'DEBUG';
 */
type LogLevelStrings = keyof typeof LogLevel;

function printImportant(key: LogLevelStrings, message: string) {
  const num = LogLevel[key];
  if (num <= LogLevel.WARN) {
    console.log("Log level key is:", key);
    console.log("Log level value is:", num);
    console.log("Log level message is:", message);
  }
}
printImportant("ERROR", "This is a message");

const enum

在大多数情况下,枚举是一种完全有效的解决方案。但有时要求会更严格。为了避免在访问枚举值时付出额外生成代码和间接访问的代价,我们可以使用常量枚举。

const enum Direction {
  Up,
  Down,
  Left,
  Right,
}

let directions = [
  Direction.Up,
  Direction.Down,
  Direction.Left,
  Direction.Right,
];

常量枚举只能使用常量枚举表达式,与常规枚举不同,它们在编译过程中会被完全删除。常量枚举成员在使用时被内联。这是因为常量枚举不能有计算成员。

"use strict";
let directions = [
    0 /* Direction.Up */,
    1 /* Direction.Down */,
    2 /* Direction.Left */,
    3 /* Direction.Right */,
];

会有一些陷阱,尽量不要使用常量枚举。

参考