简体   繁体   English

打字稿基于字符串的枚举

[英]Typescript String Based Enums

So I've read all the posts on String Based Enums in Typescript, but I couldn't find a solution that meets my requirements. 所以我已阅读了Typescript中基于字符串的枚举的所有帖子,但我找不到符合我要求的解决方案。 Those would be: 那些将是:

  • Enums that provide code completion 提供代码完成的枚举
  • Enums that can be iterated over 可以迭代的枚举
  • Not having to specify an element twice 不必两次指定元素
  • String based 基于字符串

The possibilities I've seen so far for enums in typescript are: 到目前为止我在打字稿中看到的可能性是:

  1. enum MyEnum {bla, blub} : This fails at being string based, so I can't simply read from JSONs which are string based... enum MyEnum {bla, blub} :这是基于字符串的失败,所以我不能简单地读取基于字符串的JSON ...
  2. type MyEnum = 'bla' | 'blub' type MyEnum = 'bla' | 'blub' : Not iterable and no code completion type MyEnum = 'bla' | 'blub' :不可迭代且无代码完成
  3. Do it yourself class MyEnum { static get bla():string{return "bla"} ; static get blub():string{return "blub"}} 自己动手做class MyEnum { static get bla():string{return "bla"} ; static get blub():string{return "blub"}} class MyEnum { static get bla():string{return "bla"} ; static get blub():string{return "blub"}} : Specifies elements twice class MyEnum { static get bla():string{return "bla"} ; static get blub():string{return "blub"}} :指定元素两次

So here come the questions: 所以这里有问题:

  1. There's no way to satisfy those requirements simultaneously? 有没有办法同时满足这些要求? If no, will it be possible in the future? 如果不是,将来是否可能?
  2. Why didn't they make enums string based? 他们为什么不以enums字符串为基础?
  3. Did someone experience similar problems and how did you solve them? 有人遇到类似的问题,你是如何解决的?

Why didn't they make enums string based 为什么他们没有根据枚举字符串

To be clear Enums are both number and string based in that direct access is number and reverse map is string ( more on this ). 要清楚枚举是数字字符串 ,因为直接访问是number ,反向映射是string更多内容 )。

Meeting your requirement 满足您的要求

You key reason for ruling out raw enums is 排除原始枚举的关键原因是

so I can't simply read from JSONs which are string based... 所以我不能简单地从基于字符串的JSON中读取...

You will experience the same thing eg when reading Date s cause JSON has no date data type. 您将体验相同的事情,例如,在阅读Date因为JSON没有日期数据类型。 You would new Date("someServerDateTime") to convert these. 您可以使用new Date("someServerDateTime")来转换它们。

You would use the same strategy to go from server side enum (string) to TS enum (number). 您将使用相同的策略从服务器端enum (字符串)到TS enum (数字)。 Easy done thanks to the reverse lookup MyEnum["someServerString"] 由于反向查找MyEnum["someServerString"]轻松完成

Hydration 水化

This process of converting server side data to client side active data is sometimes called Hydration. 将服务器端数据转换为客户端活动数据的过程有时称为水合。 My favorite lib for this at the moment is https://github.com/pleerock/class-transformer 我目前最喜欢的lib是https://github.com/pleerock/class-transformer

I personally handle this stuff myself at the server access level ie hand write an API that makes the XHR + does the serialization. 我亲自在服务器访问级别处理这些内容,即手写一个使XHR +进行序列化的API。

At my last job we automated this with code generation that did even more than that (supported common validation patterns between server and client code). 在我上一份工作中,我们通过代码生成实现了自动化,甚至更多(支持服务器和客户端代码之间的常见验证模式)。

I think that implementing Enum in a C-like style with numbers is fine, because an Enum (similar to a Symbol ) is usually used to declare a value that is uniquely identifiable on development time. 我认为,实现Enum与数字的C-般的风格是好的,因为Enum (类似于Symbol )通常用来声明值是唯一可识别的开发时间。 How the machine represents that value on run time doesn't really concern the developer. 机器如何在运行时表示该值并不真正与开发人员有关。

But what we developer sometimes want (because we're all lazy and still want to have all the benefits!), is to use the Enum as an API or with an API that does not share that Enum with us, even though the API is essentially an Enum because the valid value of a property only is foo and bar . 但是我们开发人员有时想要的东西(因为我们都很懒,但仍希望获得所有好处!),就是使用Enum作为API或使用不与我们共享Enum的API,即使API是本质上是一个Enum因为属性的有效值只是foobar

I guess this is the reason why some languages have string based Enums :) 我想这就是为什么有些语言有基于字符串的Enums :)

How TypeScript handles Enums TypeScript如何处理枚举

If you look at the transpiled JavaScript you can see that TypeScript just uses a plain JavaScript Object to implement an Enum . 如果查看已编译的JavaScript,您可以看到TypeScript只使用普通的JavaScript对象来实现Enum For example: 例如:

enum Color {
    Red,
    Green,
    Blue
}

will be transpiled to: 将被翻译成:

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

This means you can access the string value like Color[Color.Red] . 这意味着您可以像Color[Color.Red]一样访问字符串值。 You will still have code completion and you do not have to specify the values twice. 您仍然可以完成代码,而不必两次指定值。 But you can not just do Object.keys(Color) to iterate over the Enum , because the values exist "twice" on the object. 但是你不能只用Object.keys(Color)迭代Enum ,因为值在对象上存在“两次”。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM