Day 132/200 TypeScript 中枚举的用法

1、定义

1)使用枚举可以清晰地表达意图或创建一组有区别的用例;

2)TypeScript支持数字的和基于字符串的枚举。

2、分类

1)数字枚举

enum Direction {
    Up = 1,
    Down,
    Left,
    Right
}
//数字枚举, Up使用初始化为 1。 其余的成员会从 1开始自动增长。 
//换句话说, Direction.Up的值为 1, Down为 2, Left为 3, Right为 4。

使用的案例

enum Response {
    No = 0,
    Yes = 1,
}

function respond(recipient: string, message: Response): void {
    // ...
}

respond("Princess Caroline", Response.Yes)

注意:如果枚举中含有函数的形式,要放在后面。

enum E {
    A = getSomeValue(),
    B, // error! 'A' is not constant-initialized, so 'B' needs an initializer
}

2)字符串枚举

每个成员都使用,字符串字面量来初始化

enum Direction {
    Up = "UP",
    Down = "DOWN",
    Left = "LEFT",
    Right = "RIGHT",
}

3)异构枚举(Heterogeneous enums)

enum BooleanLikeHeterogeneousEnum {
    No = 0,
    Yes = "YES",
}

4)计算的和常量成员

无值,则会有默认值0

// E.X is constant:
enum E { X }
//这种情况下它被赋予值 0

第一个有初始值,那么就+1

// All enum members in 'E1' and 'E2' are constant.

enum E1 { X, Y, Z }

enum E2 {
    A = 1, B, C
}

其他需要计算出值的情况

  • 一个枚举表达式字面量(主要是字符串字面量或数字字面量)
  • 一个对之前定义的常量枚举成员的引用(可以是在不同的枚举类型中定义的)
  • 带括号的常量枚举表达式
  • 一元运算符 +-~其中之一应用在了常量枚举表达式
  • 常量枚举表达式做为二元运算符 +-*/%<<>>>>>&|^的操作对象。 若常数枚举表达式求值后为 NaN或 Infinity,则会在编译阶段报错。
enum FileAccess {
    // constant members
    None,
    Read    = 1 << 1,
    Write   = 1 << 2,
    ReadWrite  = Read | Write,
    // computed member
    G = "123".length
}

联合枚举与枚举成员的类型

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!
    radius: 100,
}

这里不大明白,为什么会报错,

明白了,在接口里是类型;在对象里是属性值,所以报错了。

意味着,枚举不能两者都是,做了类型。就不能是值了?[待验证]

另一个变化是枚举类型本身变成了每个枚举成员的 联合

enum E {
    Foo,
    Bar,
}

function f(x: E) {
    if (x !== E.Foo || x !== E.Bar) {
        //             ~~~~~~~~~~~
        // Error! Operator '!==' cannot be applied to types 'E.Foo' and 'E.Bar'.
    }
}

理解的是,既做了类型,又做值的比较就会有问题。

运行时的枚举

//枚举是在运行时真正存在的对象
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 Enum {
    A
}
let a = Enum.A;
let nameOfA = Enum[a]; // "A"


//编译为JavaScript为
var Enum;
(function (Enum) {
    Enum[Enum["A"] = 0] = "A";
})(Enum || (Enum = {}));
var a = Enum.A;
var nameOfA = Enum[a]; // "A"

相当于知道属性值,来知道属性。这个功能感觉挺强大。前提是,属性值不重复。

问题来了,假如重复了,是会报错,还是找到两个?

仅限于数字枚举。

 不会为字符串枚举成员生成反向映射

const枚举

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
}

在正常的枚举里,没有初始化方法的成员被当成常数成员。 对于非常数的外部枚举而言,没有初始化方法时被当做需要经过计算的。

参考链接

https://www.tslang.cn/docs/handbook/enums.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值