为什么迭代枚举在typescript中如此违反直觉?

wlzqhblo  于 2023-04-13  发布在  TypeScript
关注(0)|答案(1)|浏览(116)
enum Direction {
    Down = -1,
    Up = 1
}

let i = 1;
for (const direction of Object.values(Direction)) {
    console.log('iteration ' + i++);
    console.log(direction);
}

迭代1
向上
迭代2
-1
迭代3
向下
迭代4
1
我期待着:
迭代1
-1
迭代2
1
生成的js:

var Direction;
(function (Direction) {
    Direction[Direction["Down"] = -1] = "Down";
    Direction[Direction["Up"] = 1] = "Up";
})(Direction || (Direction = {}));
var i = 1;
for (var _i = 0, _a = Object.values(Direction); _i < _a.length; _i++) {
    var direction = _a[_i];
    console.log('iteration ' + i++);
    console.log(direction);
}

我相信有一个变通办法,但我真的只是想知道是什么原因导致这违背了我的每一个期望

x4shl7ld

x4shl7ld1#

看看生成的JavaScript输出:

var Direction;
(function (Direction) {
    Direction[Direction["Down"] = -1] = "Down";
    Direction[Direction["Up"] = 1] = "Up";
})(Direction || (Direction = {}));

我们只关注里面的两行:

Direction[Direction["Down"] = -1] = "Down";
Direction[Direction["Up"] = 1] = "Up";

赋值实际上只是“返回”分配给目标的新值的表达式。因此,在我们将-1分配给Down并将1分配给Up之后,我们将"Down"分配给-1并将"Up"分配给1,这为我们提供了一个反向Map,允许您查找枚举成员的名称:

console.log(Direction[Direction.Down]); // "Down"

基本上,你的enum在运行时看起来像这样:

{
  "1": "Up",
  "Down": -1,
  "-1": "Down",
  "Up": 1
}

然而,这种行为只在数字枚举中出现。例如,像这样的字符串枚举不会产生反向Map:

enum Direction {
    Down = "down",
    Up = "up",
}

至于修复,您可以检查该值是否为数字:

let i = 1;
for (const direction of Object.values(Direction)) {
    if (typeof direction !== "number") continue;

    console.log('iteration ' + i++);
    console.log(direction);
}

Playground

相关问题