क्या JSON से तारों के साथ टाइपस्क्रिप्ट एनम संगत होने का कोई तरीका है?JSON स्ट्रिंग से टाइपस्क्रिप्ट `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]
उपयोग कर सकते हैं कर रहा हूँ, लेकिन यह बोझिल है और enum प्रकार एनोटेशन भ्रामक और गुमराह करने वाला बनाने के लिए है, जो अपने उद्देश्य धरा लगता है। JSON तकनीकी रूप से मान्य एनम मान की आपूर्ति नहीं कर रहा है, इसलिए मुझे संपत्ति को enum में टाइप नहीं करना चाहिए।
तो क्या मैं इस समय के बजाय कर रहा हूँ स्थिर स्थिरांक के साथ एक स्ट्रिंग प्रकार उपयोग कर रहा है:
const Type = { NEW: "NEW", OLD: "OLD" }
interface Thing { type: string }
let thing:Thing = JSON.parse('{"type": "NEW"}');
alert(thing.type == Type.NEW); // true
यह मैं उपयोग मैं चाहता हूँ हो जाता है, लेकिन प्रकार एनोटेशन string
रास्ता काफ़ी व्यापक है और त्रुटियों की संभावना है।
मुझे आश्चर्य है कि जावास्क्रिप्ट के सुपरसेट में स्ट्रिंग आधारित enums नहीं है। क्या मैं कुछ भूल रहा हूँ? क्या यह अलग तरीके से किया जा सकता है?
अद्यतन टीएस 1,8
एक और विकल्प (धन्यवाद @basaret) string literal types का उपयोग करना है, लेकिन वांछित enum की तरह उपयोग (ऊपर) इसे दो बार अपने मूल्यों को परिभाषित करने की आवश्यकता है प्राप्त करने के लिए: एक बार में एक स्ट्रिंग शाब्दिक प्रकार, और एक बार (निरंतर या नाम स्थान) एक मूल्य के रूप में:
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
यह काम करता है लेकिन बॉयलरप्लेट का एक बहुत लेता है, पर्याप्त है कि मैं यह सबसे का उपयोग नहीं करते ओ एफ समय। अभी के लिए मुझे उम्मीद है कि proposal for string enums
अंततः रोडमैप बना देगा।
अद्यतन टीएस 2,1
नई keyof
type lookup स्ट्रिंग शाब्दिक प्रकार एक स्थिरांक या नाम स्थान है, जो परिभाषा एक थोड़ा कम निरर्थक बना देता है की चाबी से उत्पन्न किया जा करने के लिए अनुमति देता है:
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
अद्यतन टी एस 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 टाइप की गई है, यह केवल एक स्ट्रिंग शाब्दिक प्रकार शॉर्टेंड नहीं है, जो वास्तव में सही होगा। कुछ मुद्दों मैं टकरा गया है:
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
साथ बराबर कोड स्ट्रिंग शाब्दिक प्रकार ठीक से काम द्वारा बदल दिया ...
हाँ, मुझे लगता है कि मैं इस बारे में ओसीडी है, मैं बस चाहता हूँ मेरा सही जेएस enums। :)
धन्यवाद! काश मैं पहले किसी भी 'दावा' के बारे में पता था। अब, मैं टीएस 2 कोशिश कर रहा हूँ।4 स्ट्रिंग एम्स, और यह मूल रूप से जो चाहता था उसके करीब है ... लेकिन मुझे टीएस प्रकार की जांच के तरीके के साथ कुछ समस्याएं मिली हैं ... – Aaron
@Aaron शांत, मदद करने में खुशी! साथ ही, आप [ts-enums] (https://github.com/LMFinney/ts-enums) प्रोजेक्ट को जांचना चाहेंगे क्योंकि यह कई उपयोग मामलों के लिए बहुत बहुमुखी और शक्तिशाली enum हैंडलिंग बनाता है –