来自JSON字符串的Typescript`enum` [英] Typescript `enum` from JSON string
问题描述
有没有办法让一个TypeScript枚举与JSON的字符串兼容?
Is there any way to have a TypeScript enum compatible with strings from JSON?
例如:
enum Type { NEW, OLD }
interface Thing { type: Type }
let thing:Thing = JSON.parse('{"type": "NEW"}');
alert(thing.type == Type.NEW); // false
我会像 的东西。 type == Type.NEW
为true。或者更具体地说,我希望我可以指定要定义为字符串的枚举值,而不是数字。
I would like thing.type == Type.NEW
to be true. Or more specifically, I wish I could specify the enum
values to be defined as strings, not numbers.
我知道我可以使用 thing.type.toString()==键入[Type.NEW]
但这很麻烦,似乎使枚举类型注释混淆和误导,击败其目的。 JSON在技术上不是提供有效的枚举值,所以我不应该将属性键入枚举。
I am aware that I can use thing.type.toString() == Type[Type.NEW]
but this is cumbersome and seems to make the enum type annotation confusing and misleading, which defeats its purpose. The JSON is technically not supplying a valid enum value, so I shouldn't type the property to the enum.
所以我目前使用静态常量的字符串类型:
So what I am currently doing instead is using a string type with static constants:
const Type = { NEW: "NEW", OLD: "OLD" }
interface Thing { type: string }
let thing:Thing = JSON.parse('{"type": "NEW"}');
alert(thing.type == Type.NEW); // true
这让我得到我想要的用法,但类型注释字符串
的方式太广泛且容易出错。
This gets me the usage I want, but the type annotation string
is way too broad and error prone.
我有点惊讶,JavaScript的超集没有字符串的枚举。我错过了什么吗?有不同的方式可以做到这一点吗?
I'm a bit surprised that a superset of JavaScript doesn't have string based enums. Am I missing something? Is there a different way this can be done?
更新
字符串文字类型是另一种选择(感谢@basaret),但要获得所需的枚举类使用(上面),它需要定义您的值两次:一次在字符串文字类型联合中,一次作为常数(或命名空间):
Using string literal types is another alternative (thanks @basaret), but to get the desired enum-like usage (above) it requires defining your values twice: once in a string literal type union, and once as a constant (or a namespace):
type Type = "NEW" | "OLD";
const Type = {
NEW: "NEW" as Type,
OLD: "OLD" as Type
}
interface Thing { type: Type }
let thing:Thing = JSON.parse(`{"type": "NEW"}`);
alert(thing.type === Type.NEW); // true
这有效,但需要很多样板,足够我不使用它的时间。现在我希望提案 string enums
将最终制定路线图。
This works but takes a lot of boilerplate, enough that I don't use it most of the time. For now I'm hoping the proposal for string enums
will eventually make the roadmap.
推荐答案
如果在2.4版本之前使用Typescript有一种方法可以通过将枚举的值设置为任何
来实现枚举。
If you are using Typescript before the 2.4 release, there is a way to achieve that with enums by casting the values of your enum to any
.
a href =https://www.typescriptlang.org/play/index.html#src=enum%20Type%20%7B%0D%0A%20%20%20%20NEW%20%3D%20%22NEW% 22%2C%0D%0A%20%20%20%20OLD%20%3D%20%22OLD%22%2C%0D%0A%7D%0D%0A%0D%0Ainterface%20Thing%20%7B%20type% 3A%20Type%20%7D%0D 0A%%0D%0Alet%20thing%3AThing%20%3D%20JSON.parse( '%7B%22type%22%3A%20%22NEW%22%7D')%3B% 0D 0A%%0D%0Aalert(thing.type%20%3D%3D%20Type.NEW)%3B%20%2F%2F%20true#SRC =枚举%20Type%20%7B%0D 0A%%20%20 %20%20NEW%20%3D%20%3Cany%3E%22NEW%22%2C%0D%0A%20%20%20%20OLD%20%3D%20%3Cany%3E%22OLD%22%2C%0D %0A%7D%0D 0A%%0D%0Ainterface%20Thing%20%7B%20type%3A%2 0Type%20%7D%0D 0A%%0D%0Alet%20thing%3AThing%20%3D%20JSON.parse( '%7B%22type%22%3A%20%22NEW%22%7D')%3B%0D% 0A%0D%0Aalert(thing.type%20%3D%3D%20Type.NEW)%3B%20%2F%2F%20truerel =nofollow noreferrer>您的第一个实现示例
An example of your first implementation
enum Type {
NEW = <any>"NEW",
OLD = <any>"OLD",
}
interface Thing { type: Type }
let thing:Thing = JSON.parse('{"type": "NEW"}');
alert(thing.type == Type.NEW); // true
Typescript 2.4已经内置了对字符串枚举的支持,所以转换为 any
将不再需要,您可以在不使用 String Literal联盟类型
,这对于验证和自动完成是确定的,但对可读性和重构不是很好,具体取决于使用情景。
Typescript 2.4 has built in support for string enums already, so the cast to any
would be no longer necessary and you could achieve it without the use of String Literal Union Type
, which is ok for validation and autocomplete, but not so good for readability and refactoring, depending on the usage scenario.
这篇关于来自JSON字符串的Typescript`enum`的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!