前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Typescript 的枚举可能不是你想象的那样

Typescript 的枚举可能不是你想象的那样

原创
作者头像
zayyo
发布2023-11-29 21:45:04
940
发布2023-11-29 21:45:04
举报
文章被收录于专栏:zayyo前端zayyo前端

如果你对枚举(enum)的外观不熟悉,这里有一些示例:

代码语言:typescript
复制
enum Direction {
  Up = 1,
  Down, // 2
  Left, // 3
  Right, // 4
}

参考资料:

代码语言:txt
复制
<p>
    <a href="https://www.typescriptlang.org/docs/handbook/enums.html#reverse-mappings">枚举 - TypeScript手册</a>
</p>

枚举作为常量的集合。这可能会很有用,尤其是当你想要具有非常独特的键时:

代码语言:typescript
复制
enum DirectiveKeys {
    Skip = '__c_skip_me_',
    Remove = '__c_remove_me_',
    Add = '__c_add_me_'
}

const objectThatShouldBeSkipped = {
    action: DirectiveKeys.Skip
}

使用它们的原因:

当使用枚举时,它锁定了常量,并将其保持在可管理的对象格式中:

代码语言:typescript
复制
const DirectiveKeys = {
    Skip: '__c_skip_me_',
    Remove: '__c_remove_me_',
    Add: '__c_add_me_'
}

DirectiveKeys.Skip = '哎呀,这仍然是可变的';

const objectThatShouldBeSkipped = {
    action: DirectiveKeys.Skip // 永远不会被跳过
}

当使用枚举时,你还可以具有隐含的值:

代码语言:typescript
复制
enum ExplicitValues {
    Up = 0,
    Down = 1,
    Right = 2,
    Left = 3
}

与下面的写法相同:

代码语言:typescript
复制
enum ImplicitValues {
    Up,
    Down,
    Right,
    Left
}

不使用它们的原因:

它们没有被抽象化。没错,TypeScript 的枚举被编译进你的代码。你可能会说:“算了,反正是 TypeScript,它们知道自己在做什么。” 但他们所做的是将这个:

代码语言:typescript
复制
enum Const {
    Up,
    Down,
    Right,
    Left
}

转换成这样:

代码语言:typescript
复制
var Const;
(function (Const) {
    Const[Const["Up"] = 0] = "Up";
    Const[Const["Down"] = 1] = "Down";
    Const[Const["Right"] = 2] = "Right";
    Const[Const["Left"] = 3] = "Left";
})(Const || (Const = {}));

作为一个喜欢小型软件包的人,这是一段非常令人沮丧的代码。将枚举转换为对象/常量可以节省数百字节。为什么?

对于每个枚举,都有类似上面的 JavaScript 片段进行匹配。

生成的 JavaScript 只有在存在 TypeScript 时才能防止突变。否则它可以很容易地被覆盖,这是枚举类型的一个主要卖点。

这是使用 Proxy 生成枚举的原始方法:

代码语言:typescript
复制
const Enum = (enums) => {
    Object.entries(enums).forEach((enums, [ key, value ]) => {
        enums[value] = key;
        return enums;
    })
    return new Proxy(enums, {
        get(target, key) {
            return target[key];
        },
        removeProperty: () => false,
        set: () => false,
    })
}

这禁止了添加或删除属性的能力,同时生成了 TypeScript 枚举生成的交替键值。

另一个好处?它是可重用的,并且不会创建相同代码的多个副本!

代码语言:typescript
复制
const Directions = Enum({
    Up: 1,
    Down: 2,
    Right: 3,
    Left: 4
});

const Compass = Enum([
    "North",
    "East",
    "South",
    "West"
]);

哇,对于任何人来说都可以使用的生产就绪代码,太棒了!

现在等一下。

我的代码片段与 TypeScript 生成的代码的区别在于,我的代码利用了 ES6+ 的功能,比如 Proxy。如果你的目标受众不包括这个,那我只能说抱歉。

我的代码片段也没有 Microsoft 和 TypeScript 团队的支持,这意味着它没有经过充分的测试。

使用 TypeScript 枚举的最终和最重要的原因是?它们具有所有的智能提示优势。也许有一天我会为我的小函数开发一个相同的智能提示类型。

在那之前,随便你怎么做吧。

附言:

我认为生成的代码可能需要稍微更新一下。比如,使用箭头函数应该没问题。

代码语言:typescript
复制
var Const;
((Const) => {
    Const[Const["Up"] = 0] = "Up";
    Const[Const["Down"] = 1] = "Down";
    Const[Const["Right"] = 2] = "Right";
    Const[Const["Left"] = 3] = "Left";
})(Const || (Const = {}));

我正在参与2023腾讯技术创作特训营第三期有奖征文,组队打卡瓜分大奖!

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
http://www.vxiaotou.com