TypeScript में enum नाम कैसे प्राप्त करें: हुड के नीचे का जादू

शुरुआती लोगों के लिए ऑनलाइन Python प्रशिक्षक

Python आसानी से सीखें बिना सिद्धांत के बोझ के। स्वचालित जांच के साथ व्यावहारिक कार्य हल करें और ब्राउज़र में सीधे कोड लिखें।

पाठ्यक्रम शुरू करें

प्रस्तावना: Stack Overflow पर शाश्वत प्रश्न

\n\n

क्या आपने कभी सोचा है कि TypeScript पर अनुभवी डेवलपर्स enum के मानों के नाम कैसे प्राप्त करते हैं? यदि आपने Stack Overflow पर देखा है, तो आपने निश्चित रूप से हज़ारों व्यूज़ वाला एक प्रश्न देखा होगा: "How to get names of enum entries?"। इसमें मुश्किल क्या है, ऐसा लगता है? लेकिन व्यवहार में, कई नौसिखिए (और केवल वे ही नहीं) इस बिंदु पर फंस जाते हैं।

\n\n

इस लेख में, हम केवल तैयार उत्तर नहीं देंगे। हम TypeScript के हुड के नीचे जाएंगे और समझेंगे कि enum वास्तव में कैसे काम करते हैं, कंपाइलर उन्हें JavaScript में कैसे बदलता है, और नाम प्राप्त करने के कुछ तरीके अप्रत्याशित बग क्यों पैदा कर सकते हैं। तैयार हैं? चलिए शुरू करते हैं!

\n\n

TypeScript में enum क्या है और उनके नामों की आवश्यकता क्यों है?

\n\n

Enum (गणना) नामित स्थिरांकों का एक सेट निर्दिष्ट करने का एक सुविधाजनक तरीका है। TypeScript में, वे संख्यात्मक (डिफ़ॉल्ट रूप से) और स्ट्रिंग हो सकते हैं। लेकिन यदि आपको किसी विशिष्ट मान का नाम प्राप्त करने की आवश्यकता हो तो क्या करें? उदाहरण के लिए, आपको API से स्टेटस कोड 403 मिला, और आप उपयोगकर्ता को एक समझने योग्य संदेश "Forbidden" दिखाना चाहते हैं।

\n\n
enum HttpStatus {\n  OK = 200,\n  NotFound = 404,\n  Forbidden = 403\n}\n\n// हमारा कार्य: मान 403 से नाम "Forbidden" प्राप्त करना\n
\n\n

ऐसा लगता है कि TypeScript को इसके लिए एक अंतर्निहित विधि प्रदान करनी चाहिए। लेकिन ऐसा नहीं है। हमें अपना तर्क लिखना होगा। और यहीं से सबसे दिलचस्प शुरुआत होती है।

\n\n

सीधा समाधान: Object.keys और Object.values

\n\n

सबसे स्पष्ट तरीका Object.keys() या Object.values() विधियों का उपयोग करना है। कई नौसिखिए कुछ इस तरह लिखते हैं:

\n\n
function getEnumName(enumObj: any, value: number): string | undefined {\n  const keys = Object.keys(enumObj);\n  return keys.find(key => enumObj[key] === value);\n}\n\nconsole.log(getEnumName(HttpStatus, 403)); // "Forbidden" — काम करता है!\n
\n\n

तार्किक लगता है? हाँ। लेकिन यदि आप इस कोड को संख्यात्मक enum पर आज़माते हैं, तो आपको एक आश्चर्य का सामना करना पड़ेगा। आइए देखें कि हमारा HttpStatus किसमें कंपाइल होता है।

\n\n

हुड के नीचे: संख्यात्मक enum का कंपाइलेशन

\n\n

जब TypeScript संख्यात्मक enum को कंपाइल करता है, तो यह रिवर्स मैपिंग (reverse mapping) के साथ एक ऑब्जेक्ट बनाता है। कंपाइल किया गया JavaScript इस तरह दिखता है:

\n\n
var HttpStatus;\n(function (HttpStatus) {\n    HttpStatus[HttpStatus["OK"] = 200] = "OK";\n    HttpStatus[HttpStatus["NotFound"] = 404] = "NotFound";\n    HttpStatus[HttpStatus["Forbidden"] = 403] = "Forbidden";\n})(HttpStatus || (HttpStatus = {}));\n\n// अंत में, HttpStatus ऑब्जेक्ट इस तरह दिखता है:\n// { \n//   "200": "OK", \n//   "404": "NotFound", \n//   "403": "Forbidden", \n//   "OK": 200, \n//   "NotFound": 404, \n//   "Forbidden": 403 \n// }\n
\n\n

चाल देखी? कंपाइलर संख्या-कुंजियाँ और स्ट्रिंग-कुंजियाँ दोनों जोड़ता है। इसलिए, Object.keys(HttpStatus) केवल ["OK", "NotFound", "Forbidden"] ही नहीं, बल्कि ["200", "404", "403"] भी लौटाएगा। यह हमारे सरल समाधान के तर्क को तोड़ देता है!

\n\n

इससे बचने के लिए, संख्यात्मक कुंजियों को फ़िल्टर करना होगा:

\n\n
function getEnumNameSafe(enumObj: any, value: number): string | undefined {\n  const keys = Object.keys(enumObj).filter(key => isNaN(Number(key)));\n  return keys.find(key => enumObj[key] === value);\n}\n
\n\n

लेकिन ऐसा कोड टेढ़ा लगता है। क्या कोई बेहतर तरीका है?

\n\n

स्ट्रिंग enum: एक अलग कहानी

\n\n

यदि आप स्ट्रिंग enum का उपयोग करते हैं, तो रिवर्स मैपिंग नहीं बनाई जाती है। यह कार्य को सरल बनाता है:

\n\n
enum Direction {\n  Up = "UP",\n  Down = "DOWN",\n  Left = "LEFT",\n  Right = "RIGHT"\n}\n\n// Object.keys(Direction) केवल ["Up", "Down", "Left", "Right"] लौटाएगा — एकदम सही!\n
\n\n

लेकिन क्या होगा यदि आपको मान से नाम प्राप्त करने की आवश्यकता है? वही Object.keys पूरी तरह से काम करता है:

\n\n
function getStringEn                

ब्लॉग

पुस्तक अनुशंसाएँ