有沒有辦法讓TypeScript的枚舉與來自JSON的字符串兼容?來自JSON字符串的Typescript`enum`
例如:
enum Type { NEW, OLD }
interface Thing { type: Type }
let thing:Thing = JSON.parse('{"type": "NEW"}');
alert(thing.type == Type.NEW); // false
我會像thing.type == Type.NEW
是真實的。或者更具體地說,我希望我可以指定enum
值定義爲字符串,而不是數字。
我知道,我可以使用thing.type.toString() == Type[Type.NEW]
,但這很麻煩,似乎使枚舉類型註釋混淆和誤導,這打破了它的目的。 JSON在技術上是而不是提供了一個有效的枚舉值,所以我不應該輸入屬性枚舉。
那麼,我現在做的,而不是使用字符串類型與靜態常量:
const Type = { NEW: "NEW", OLD: "OLD" }
interface Thing { type: string }
let thing:Thing = JSON.parse('{"type": "NEW"}');
alert(thing.type == Type.NEW); // true
這讓我我想要的用法,但類型標註string
是太寬泛,容易出錯。
我有點驚訝,JavaScript的超集沒有基於字符串的枚舉。我錯過了什麼嗎?有沒有不同的方式可以做到這一點?
更新TS 1.8
使用string literal types是另一種選擇(感謝@basaret),但以獲得所需的枚舉類使用(上圖)它需要定義兩次你的價值觀:在一次一個字符串字面型,一次作爲值(常量或命名空間):
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
這工作,但需要大量的樣板,以至於我不使用最多的IT運時間。現在我希望proposal for string enums
最終能夠制定路線圖。
更新TS 2.1
新keyof
type lookup允許從一個const或命名空間,這使得定義一個小較少冗餘的鍵所產生的字符串文字類型:
namespace Type {
export const OLD = "OLD";
export const NEW = "NEW";
}
type Type = keyof typeof Type;
interface Thing { type: Type }
const thing: Thing = JSON.parse('{"type": "NEW"}');
thing.type == Type.NEW // true
更新T S 2.4
TypeScript 2.4 added support for string enums!上面的例子就變成:
enum Type {
OLD = "OLD",
NEW = "NEW"
}
interface Thing { type: Type }
const thing: Thing = JSON.parse('{"type": "NEW"}');
alert(thing.type == Type.NEW) // true
這看起來近完美的,但還是有一些心痛:
- 您仍然有寫值的兩倍,即
OLD = "OLD"
,而且也沒有確認活動你沒有一個錯字,如NEW = "MEW"
......這已經讓我陷入了真實的代碼。 有一些古怪的東西(也許是錯誤?)與如何檢查枚舉類型,它不只是一個字符串文字類型的簡寫,這是真正正確的。我已經碰到了一些問題:
enum Color { RED = "RED", BLUE = "BLUE", GREEN = "GREEN" } type ColorMap = { [P in Color]: number; } declare const color: Color; declare const map: ColorMap; map[color] // Error: Element implicitly has an 'any' type because type 'ColorMap' has no index signature. const red: Color = "RED"; // Type '"RED"' is not assignable to type 'Color'. const blue: Color = "BLUE" as "RED" | "BLUE" | "GREEN"; // Error: Type '"RED" | "BLUE" | "GREEN"' is not assignable to type 'Color'.
與
enum Color
等效代碼由字符串字面類型做工精細取代...
是啊,我覺得我有這個強迫症,我只是想我完美的JS枚舉。 :)
謝謝!我希望我以前知道這個「任何」的斷言。現在,我正在嘗試TS 2。4個字符串枚舉,它與我原本想要的非常接近......但是我發現了TS類型檢查它的一些問題...... – Aaron
@Aaron很酷,很高興幫助!另外,你可能想要檢查[ts-enums](https://github.com/LMFinney/ts-enums)項目,因爲它使枚舉處理對於很多用例非常靈活和強大 –