enum और radio-बटन एक आदर्श जोड़ी क्यों हैं?
\nकल्पना करें: आप TypeScript में एक फॉर्म लिख रहे हैं। उपयोगकर्ता को कई विकल्पों में से एक चुनने देना है — उदाहरण के लिए, कठिनाई स्तर, ऑर्डर स्थिति या लिंग। इन विकल्पों को कहाँ संग्रहीत करें? आप स्ट्रिंग्स की एक ऐरे को हार्डकोड कर सकते हैं, लेकिन यह एक गलत रास्ता है। जब विकल्प अधिक हो जाएंगे, तो आप भ्रमित हो जाएंगे, और यदि व्यावसायिक तर्क बदलता है — तो आपको दस स्थानों पर कोड बदलना होगा।
\nयहाँ enum (गणनाएँ) दृश्य पर आते हैं। वे नामित स्थिरांकों का एक सेट परिभाषित करने की अनुमति देते हैं, जो मानव द्वारा पढ़े जा सकते हैं और मशीन द्वारा समझे जा सकते हैं। और radio-बटन सूची से एक मान चुनने के लिए एक क्लासिक UI तत्व हैं। उन्हें जोड़ने का मतलब है स्वच्छ, रखरखाव योग्य कोड प्राप्त करना। यह अच्छा लगता है, लेकिन एक बारीक बात है: टेम्पलेट में प्रदर्शित करने के लिए enum को कैसे iterate करें? यह वही सवाल है जो Stack Overflow पर हजारों डेवलपर्स को परेशान करता है। आइए इसे हमेशा के लिए समझ लें।
\n\nसमस्या: enum एक ऐरे नहीं है
\nTypeScript में, enum केवल स्ट्रिंग्स की एक सूची नहीं है। यह इस बात पर निर्भर करता है कि आपने इसे कैसे घोषित किया है (संख्यात्मक या स्ट्रिंग), यह अलग-अलग व्यवहार करता है। संख्यात्मक enum एक रिवर्स मैपिंग बनाता है: key -> value और value -> key। स्ट्रिंग enum केवल आगे की मैपिंग बनाता है। इसलिए केवल for (let item in MyEnum) लिखना एक बुरा विचार है। आपको न केवल आवश्यक keys मिलेंगी, बल्कि अनावश्यक रिवर्स मैपिंग भी मिलेगी।
यहाँ एक सामान्य जाल है:
\nenum Status {\n Active = 1,\n Inactive = 2,\n Pending = 3\n}\n\n// ऐसा न करें\nfor (let key in Status) {\n console.log(key); // "1", "2", "3", "Active", "Inactive", "Pending"\n}\n\nदेखा? कंसोल में नाम और मान दोनों आ गए। यदि आप इसे radio-बटन में प्रदर्शित करने का प्रयास करते हैं, तो उपयोगकर्ता को समझ में न आने वाले अंक दिखाई देंगे। यह हमारे लिए उपयुक्त नहीं है।
\n\nसमाधान #1: स्ट्रिंग enum के लिए Object.values()
\nसबसे सरल और विश्वसनीय तरीका Object.values() का उपयोग करना है। यह विधि ऑब्जेक्ट के गणनीय गुणों के मानों की एक ऐरे लौटाती है। स्ट्रिंग enum के लिए यह पूरी तरह से काम करता है, क्योंकि उनमें (लगभग हमेशा) रिवर्स मैपिंग नहीं होती है।
उदाहरण: ऑर्डर स्थिति
\nenum OrderStatus {\n New = 'new',\n Processing = 'processing',\n Shipped = 'shipped',\n Delivered = 'delivered',\n Cancelled = 'cancelled'\n}\n\n// मानों की ऐरे प्राप्त करें\nconst statusValues = Object.values(OrderStatus);\n// ['new', 'processing', 'shipped', 'delivered', 'cancelled']\n\n// अब टेम्पलेट में आसानी से प्रदर्शित किया जा सकता है (React)\nfunction StatusSelector() {\n return (\n <div>\n {statusValues.map((status) => (\n <label key={status}>\n <input type="radio" name="status" value={status} />\n {status}\n </label>\n ))}\n </div>\n );\n}\n\nसब कुछ बहुत सरल है। हमें स्ट्रिंग्स की एक ऐरे मिली और हमने इसे iterate किया। यह React, Angular, Vue — किसी भी फ्रेमवर्क के लिए उपयुक्त है।
\n\nसमाधान #2: संख्यात्मक enum के लिए Object.keys() + फ़िल्टरिंग
\nसंख्यात्मक enum के साथ स्थिति अधिक पेचीदा है। Object.values() न केवल स्ट्रिंग keys बल्कि संख्यात्मक मान भी लौटाएगा, क्योंकि JavaScript उन्हें ऑब्जेक्ट के "गुण" मानता है। हमें केवल स्ट्रिंग्स (keys) को फ़िल्टर करने की आवश्यकता है।
उदाहरण: एक्सेस स्तर
\nenum AccessLevel {\n Guest = 0,\n User = 1,\n Moderator = 2,\n Admin = 3\n}\n\n// फ़िल्टर करें: केवल स्ट्रिंग्स (keys) रखें\nconst levelKeys = Object.keys(AccessLevel).filter(key => isNaN(Number(key)));\n// ['Guest', 'User', 'Moderator', 'Admin']\n\n// यदि आसान प्रदर्शन के लिए ऑब्जेक्ट्स की ऐरे चाहिए\nconst levelOptions = levelKeys.map(key => ({\n label: key,\n value: AccessLevel[key as keyof typeof AccessLevel]\n}));\n// [\n// { label: 'Guest', value: 0 },\n// { label: 'User', value: 1 },\n// ...\n// ]\n\nअब आपके पास विकल्पों की एक ऐरे है, जहाँ label मानव-पठनीय नाम है और value एक संख्यात्मक कोड है, जो सुविधाजनक है।