Skip to content
标签
note
字数
508 字
阅读时间
3 分钟

和字面量类型的关系

在类型保护的场景中,除了使用 枚举类型,也可以使用 联合类型+字面量

ts
type Easing = "ease-in" | "ease-out" | "ease-in-out";
class UIElement {
    animate(dx: number, dy: number, easing: Easing) {
        if (easing === "ease-in") {
            // ...
        }
        else if (easing === "ease-out") {
        }
        else if (easing === "ease-in-out") {
        }
        else {
            // error! should not pass null or undefined.
        }
    }
}

let button = new UIElement();
button.animate(0, 0, "ease-in");
button.animate(0, 0, "uneasy"); // error: "uneasy" is not allowed here
  • 字面量类型:通过多个对象类型的联合,来实现手动的互斥属性

和对象的关系

对象是单向映射的,我们只能从键映射到键值。而枚举是双向映射的,即你可以从枚举成员映射到枚举值,也可以从枚举值映射到枚举成员

ts
enum Items2 {
  Foo,
  Bar,
  Baz
}

const fooValue = Items.Foo; // 0
const fooKey = Items[0]; // "Foo"

要了解这一现象的本质,我们需要来看一看枚举的编译产物,如以上的枚举会被编译为以下 JavaScript 代码
复制代码

js
(function (Items) {
    Items[Items["Foo"] = 0] = "Foo";
    Items[Items["Bar"] = 1] = "Bar";
    Items[Items["Baz"] = 2] = "Baz";
})(Items || (Items = {}));

obj[k] = v 的返回值即是 v,因此这里的 obj[obj[k] = v] = k 本质上就是进行了 obj[k] = v 与 obj[v] = k 这样两次赋值

但需要注意的是,仅有值为数字的枚举成员才能够进行这样的双向枚举,字符串枚举成员仍然只会进行单次映射:

js
enum Items {
  Foo,
  Bar = "BarValue",
  Baz = "BazValue"
}

// 编译结果,只会进行 键-值 的单向映射
"use strict";
var Items;
(function (Items) {
    Items[Items["Foo"] = 0] = "Foo";
    Items["Bar"] = "BarValue";
    Items["Baz"] = "BazValue";
})(Items || (Items = {}));

常量枚举

它和普通枚举的差异主要在访问性与编译产物。对于常量枚举,你只能通过枚举成员访问枚举值(而不能通过值访问成员)

ts
const enum Items3 {
    Foo,
    Bar,
    Baz
  }
  const fooValue1 = Items.Foo; // 0

参考

字面量类型和枚举 - 掘金

贡献者

The avatar of contributor named as jiechen jiechen

页面历史

撰写