来自JSON字符串的Typescript`enum` [英] Typescript `enum` from JSON string

查看:101
本文介绍了来自JSON字符串的Typescript`enum`的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有没有办法让一个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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆