TypeScript त्रुटि: यूनियन प्रकार से इंडेक्स - शुरुआती लोगों के लिए समाधान

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

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

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

परिचय: TypeScript आपके कोड पर क्यों भड़कता है?

\n\n

क्या आपने कभी TypeScript में ऐसा कोड लिखा है जो बिल्कुल तार्किक लगता है, लेकिन कंपाइलर अचानक एक डरावनी त्रुटि देता है? यदि आपने "An index signature parameter type cannot be a union type. Consider using a mapped object type instead" संदेश का सामना किया है - तो आप अकेले नहीं हैं। यह त्रुटि Stack Overflow पर सबसे लोकप्रिय प्रश्नों में से एक है (हज़ारों व्यूज़!), और यह अक्सर अनुभवी डेवलपर्स को भी हैरान कर देती है।

\n\n

इस लेख में, हम केवल त्रुटि को ठीक करने का तरीका नहीं दिखाएंगे। हम समझेंगे कि TypeScript क्यों इतना सख्त है, और mapped object types का उपयोग कैसे करें ताकि आपका कोड न केवल काम करे बल्कि अधिक सुरक्षित भी हो। चलिए शुरू करते हैं!

\n\n

index signature क्या है और इसकी आवश्यकता क्यों है?

\n\n

कल्पना करें कि आप एक ऐसा ऑब्जेक्ट बना रहे हैं जिसकी कुंजियाँ स्ट्रिंग हैं और मान संख्याएँ हैं। उदाहरण के लिए, उत्पादों की कीमतों का एक शब्दकोश:

\n\n
// सामान्य ऑब्जेक्ट\nconst prices = {\n  apple: 100,\n  banana: 50,\n  cherry: 200\n};
\n\n

लेकिन क्या होगा यदि आप TypeScript को बताना चाहते हैं: "देखो, इस ऑब्जेक्ट में कोई भी स्ट्रिंग कुंजी हो सकती है, और सभी मान संख्याएँ होंगी"? इसके लिए index signature की आवश्यकता है - एक विशेष सिंटैक्स जो ऑब्जेक्ट के सभी गुणों के लिए एक टेम्पलेट का वर्णन करता है:

\n\n
// Index signature: [key: string]: number\ninterface PriceMap {\n  [key: string]: number;\n}\n\nconst prices: PriceMap = {\n  apple: 100,\n  banana: 50\n};
\n\n

यहाँ [key: string]: number ही index signature है। यह कहता है: "कुंजियाँ स्ट्रिंग हैं, मान संख्याएँ हैं"। सरल है, है ना?

\n\n

union-प्रकारों में समस्या क्या है?

\n\n

अब कल्पना करें कि आप संभावित कुंजियों को केवल दो विकल्पों तक सीमित करना चाहते हैं: 'name' या 'age'। ऐसा लिखना तार्किक लगता है:

\n\n
// ❌ त्रुटि! ऐसा नहीं कर सकते\ninterface Person {\n  [key: 'name' | 'age']: string | number;\n}
\n\n

और तब TypeScript वही त्रुटि देता है: "An index signature parameter type cannot be a union type. Consider using a mapped object type instead"।

\n\n

क्यों? क्योंकि index signature असीमित कुंजियों के सेट का वर्णन करने के लिए है। यदि आप कुंजियों की एक विशिष्ट सूची निर्धारित करना चाहते हैं, तो यह एक टेम्पलेट नहीं, बल्कि संरचना का सटीक विवरण है। TypeScript इन अवधारणाओं को मिश्रित करने की अनुमति नहीं देता।

\n\n

त्रुटि कैसे ठीक करें? Mapped Object Type का उपयोग करें

\n\n

कंपाइलर स्वयं जो समाधान सुझाता है वह है mapped object type (मैप किया गया ऑब्जेक्ट प्रकार) का उपयोग करना। यह जटिल लगता है, लेकिन वास्तव में यह union-प्रकार से सभी कुंजियों को "पुनरावृत्त" करने और प्रत्येक के लिए एक गुण बनाने का एक तरीका है।

\n\n

यह इस प्रकार दिखता है:

\n\n
// ✅ सही: mapped type का उपयोग करें\ntype Person = {\n  [K in 'name' | 'age']: K extends 'name' ? string : number;\n};\n\n// या एक सरल संस्करण, यदि मानों के प्रकार समान हैं:\ntype PersonSimple = {\n  [K in 'name' | 'age']: string | number;\n};
\n\n

सिंटैक्स [K in 'name' | 'age'] को समझते हैं:

\n
    \n
  • K - एक चर है जो बारी-बारी से union-प्रकार से प्रत्येक मान लेता है ('name', फिर 'age')।
  • \n
  • in - एक कीवर्ड है जो प्रकारों पर "लूप" शुरू करता है।
  • \n
  • 'name' | 'age' - हमारी कुंजियों का सेट।
  • \n
\n\n

परिणामस्वरूप, TypeScript दो विशिष्ट गुणों वाला एक ऑब्जेक्ट बनाएगा: name और age। त्रुटि गायब हो गई!

\n\n

विभिन्न मान प्रकारों के साथ उदाहरण

\n\n

अक्सर ऐसा होता है कि विभिन्न कुंजियों के लिए विभिन्न प्रकार के मान होने चाहिए। सशर्त प्रकारों (conditional types) की मदद से इसे सुरुचिपूर्ण ढंग से हल किया जाता है:

\n\n
type Config = {\n  [K in 'host' | 'port' | 'debug']: \n    K extends 'host' ? string :\n    K extends 'port' ? number :\n    boolean;\n};\n\n// अब:                

ब्लॉग

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