枚举
// 数值型枚举
enum Direction {
Up = 1,
Down,
Left,
Right,
}
// Up=0
enum Direction {
Up,
Down,
Left,
Right,
}
// 使用枚举
enum Response {
No = 0,
Yes = 1,
}
function respond(recipient: string, message: Response): void {
// ...
}
respond("Princess Caroline", Response.Yes)
// 使用计算量初始化的枚举值之后的枚举值不能没有初始化器
enum E {
A = getSomeValue(),
B, // Error! Enum member must have initializer.
}
// 字符串枚举
enum Direction {
Up = "UP",
Down = "DOWN",
Left = "LEFT",
Right = "RIGHT",
}
// 混合型枚举
enum BooleanLikeHeterogeneousEnum {
No = 0,
Yes = "YES",
}
常量枚举值和计算量枚举值
// 常量枚举值的三种情况
// 1. 枚举中第一个成员,如果不带初始化器,其值为 0。
// E.X is constant:
enum E { X }
// 2. 不带初始化器并且前一个成员为数值型常量,则其值为前一个成员的值加一。
// All enum members in 'E1' and 'E2' are constant.
enum E1 { X, Y, Z }
enum E2 {
A = 1, B, C
}
// 3. 使用常量表达式初始化的枚举值
// 其他情况则属于计算量枚举值
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! Type 'ShapeKind.Square' is not assignable to type 'ShapeKind.Circle'.
radius: 100,
}
// 特殊语义2:该枚举类型成为各个成员类型的联合类型
enum E {
Foo,
Bar,
}
function f(x: E) {
if (x !== E.Foo || x !== E.Bar) {
// ~~~~~~~~~~~
// Error! This condition will always return 'true' since the types 'E.Foo' and 'E.Bar' have no overlap.
}
}
// 运行期枚举
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.
f(E);
// 编译期枚举
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');
// 逆向映射
// 枚举中每个成员都是属性名,此外每个成员的值都可以逆向映射到属性名
// 字符串枚举成员不会生成逆向映射
enum Enum {
A
}
let a = Enum.A;
let nameOfA = Enum[a]; // "A"
// 可能会被编译成
var Enum;
(function (Enum) {
Enum[Enum["A"] = 0] = "A";
})(Enum || (Enum = {}));
var a = Enum.A;
var nameOfA = Enum[a]; // "A"
// 常量枚举
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]
// 可能会被编译成
var directions = [0 /* Up */, 1 /* Down */, 2 /* Left */, 3 /* Right */];
// 已经存在的枚举值
declare enum Enum {
A = 1,
B,
C = 2
}