【问题标题】:Typescript String Based Enums基于 Typescript 字符串的枚举
【发布时间】:2016-09-02 08:32:24
【问题描述】:

所以我已经阅读了关于 Typescript 中基于字符串的枚举的所有帖子,但我找不到满足我要求的解决方案。那些是:

  • 提供代码补全的枚举
  • 可以迭代的枚举
  • 不必指定一个元素两次
  • 基于字符串

到目前为止,我在 typescript 中看到的枚举的可能性是:

  1. enum MyEnum {bla, blub}:这在基于字符串时失败了,所以我不能简单地从基于字符串的 JSON 中读取...
  2. type MyEnum = 'bla' | 'blub': 不可迭代且无代码完成
  3. 自己动手class MyEnum { static get bla():string{return "bla"} ; static get blub():string{return "blub"}}:指定元素两次

那么问题来了:

  1. 有没有办法同时满足这些要求?如果没有,以后有可能吗?
  2. 他们为什么不让enums 基于字符串?
  3. 是否有人遇到过类似的问题,您是如何解决的?

【问题讨论】:

标签: json string typescript enums code-completion


【解决方案1】:

我认为以 C 风格的数字实现Enum 很好,因为Enum(类似于Symbol)通常用于声明在开发时可唯一标识的值。机器如何在运行时表示该值并不真正关心开发人员。

但是我们开发人员有时想要的(因为我们都很懒,仍然希望拥有所有的好处!),就是使用 Enum 作为 API 或使用 API不要与我们分享 Enum,即使 API 本质上是 Enum,因为属性的有效值只有 foobar

我想这就是为什么某些语言有基于字符串的原因Enums :)

TypeScript 如何处理枚举

如果您查看转译后的 JavaScript,您会发现 TypeScript 只是使用纯 JavaScript 对象来实现 Enum。例如:

enum Color {
    Red,
    Green,
    Blue
}

将被转译为:

{
  0: "Red",
  1: "Green",
  2: "Blue",
  Blue: 2,
  Green: 1,
  Red: 0
}

这意味着您可以访问像Color[Color.Red] 这样的字符串值。您仍然可以完成代码,并且不必指定两次值。 但是您不能只使用Object.keys(Color) 来迭代Enum,因为这些值在对象上存在“两次”。

【讨论】:

    【解决方案2】:

    他们为什么不让枚举基于字符串

    需要明确的是,枚举既是 number 又是 string,因为直接访问是 number,反向映射是 string (more on this)。

    满足您的要求

    您排除原始枚举的关键原因是

    所以我不能简单地从基于字符串的 JSON 中读取...

    你会经历同样的事情,例如读取Dates 时导致 JSON 没有日期数据类型。你会new Date("someServerDateTime") 来转换这些。

    您将使用相同的策略从服务器端 enum(字符串)转到 TS enum(数字)。借助反向查找MyEnum["someServerString"]

    ,轻松完成

    补水

    这种将服务器端数据转换为客户端活动数据的过程有时称为水合。目前我最喜欢的库是https://github.com/pleerock/class-transformer

    我亲自在服务器访问级别处理这些东西,即手写一个API,使XHR + 进行序列化。

    在我的上一份工作中,我们通过代码生成实现了自动化,其功能远不止于此(支持服务器和客户端代码之间的通用验证模式)。

    【讨论】:

    • “枚举既是数字又是字符串”-> 好的,但我想做一些类似的事情,例如在角度ng-if="myObject.type === 'bla'" 中,这不起作用,除非我做你提到的水合作用。我更喜欢的是一个纯粹基于字符串的枚举枚举,有点像问题中的 DIY 类。像打字稿那样为枚举使用混合数字/字符串映射有什么好处吗?
    • 我认为您正在尝试使用无法解决问题的语言功能。但是您始终可以实现一个简单的方法来“实现”基于字符串的枚举。此外,您可以使用 TypeScript 的 Enum 与 ng-if 一起使用。你只需要做ng-if="myObject.type === TypeEnum.Bla"
    • 对不起... 错字:ng-if="myObject.type === TypeEnum[TypeEnum.Bla]"
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-02-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-30
    相关资源
    最近更新 更多