zwvista

导航

TypeScript语言学习笔记(4)枚举

枚举

// 数值型枚举
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
}

posted on 2019-12-09 08:37  zwvista  阅读(357)  评论(0编辑  收藏  举报