JavaScript में Generics क्या हैं और क्यों ज़रूरी हैं?
\n\nकल्पना करें कि आप एक ऐसा फंक्शन लिख रहे हैं जो अलग-अलग डेटा टाइप — नंबर, स्ट्रिंग, ऑब्जेक्ट — के साथ काम करे। Generics (जेनेरिक्स) के बिना आपको या तो कोड डुप्लिकेट करना होगा या any का उपयोग करके टाइप कंट्रोल खोना होगा। Generics एक ऐसा मैकेनिज़्म है जो आपको ऐसे कम्पोनेंट (फंक्शन, क्लास, इंटरफ़ेस) बनाने देता है जो किसी भी डेटा टाइप के साथ काम करें, लेकिन टाइप की जानकारी बनाए रखें।
हालाँकि JavaScript एक डायनामिक टाइपिंग वाली भाषा है, Node.js इकोसिस्टम में TypeScript का व्यापक उपयोग होता है जो स्टैटिक टाइपिंग जोड़ता है। TypeScript में ही Generics पूरी ताकत से काम करते हैं। लेकिन इनके सिद्धांतों को समझना शुद्ध JavaScript के लिए भी फायदेमंद है — खासकर अगर आप लाइब्रेरी लिखते हैं या आधुनिक फ्रेमवर्क के साथ काम करते हैं।
\n\nइस लेख में हम जानेंगे:
\n- \n
- Generics की ज़रूरत क्यों है \n
- TypeScript में Generics कैसे घोषित और उपयोग करें \n
- Node.js के लिए उदाहरण (API, डेटा प्रोसेसिंग) \n
- सीमाएँ और बेस्ट प्रैक्टिसेज़ \n
Generics की मूल बातें: सिंटैक्स और बुनियादी उदाहरण
\n\nपहला Generic: identity फंक्शन
\n\nक्लासिक उदाहरण — एक फंक्शन जो जो इनपुट में मिले उसे वापस लौटाता है:
\n\n// Generics के बिना\nfunction identity(value: any): any {\n return value;\n}\n\n// Generics के साथ\nfunction identity<T>(value: T): T {\n return value;\n}\n\n// उपयोग\nconst num = identity<number>(42); // num — number\nconst str = identity<string>('नमस्ते'); // str — string\n\n\nप्रतीक <T> एक टाइप पैरामीटर है। आप इसे अपनी इच्छानुसार नाम दे सकते हैं (T, U, Item), लेकिन परंपरा T (Type से) का उपयोग करने की है।
एकाधिक पैरामीटर वाले Generics
\n\nकभी-कभी एक साथ कई टाइप के साथ काम करना होता है:
\n\nfunction pair<T, U>(first: T, second: U): [T, U] {\n return [first, second];\n}\n\nconst result = pair<number, string>(1, 'एक');\n// result: [number, string]\n\n\nएरो फंक्शन में Generics (Node.js)
\n\nReact या यूटिलिटीज़ में अक्सर Generics के साथ एरो फंक्शन का उपयोग होता है:
\n\nconst wrapInArray = <T>(item: T): T[] => {\n return [item];\n};\n\nconst arr = wrapInArray('परीक्षण'); // arr: string[]\n\n\nवास्तविक Node.js प्रोजेक्ट्स में Generics का उपयोग
\n\nटाइप किए गए रिस्पॉन्स के साथ API हैंडलर
\n\nमान लीजिए आप API अनुरोधों के लिए एक सामान्य फंक्शन लिख रहे हैं। Generics के बिना आप डेटा टाइप खो देंगे:
\n\n// खराब: any\nasync function fetchData(url: string): Promise<any> {\n const response = await fetch(url);\n return response.json();\n}\n\n// अच्छा: Generics\nasync function fetchData<T>(url: string): Promise<T> {\n const response = await fetch(url);\n return response.json();\n}\n\n// उपयोग\ninterface User {\n id: number;\n name: string;\n}\n\nconst user = await fetchData<User>('/api/user/1');\nconsole.log(user.name); // TypeScript जानता है कि name — string है\n\n\nटाइप किए गए डेटा कलेक्शन
\n\nडेटाबेस (जैसे Prisma या Mongoose) के साथ काम करते समय, Generics सामान्य रिपॉजिटरी बनाने में मदद करते हैं:
\n\nclass Repository<T extends { id: number }> {\n private items: T[] = [];\n\n add(item: T): void {\n this.items.push(item);\n }\n\n getById(id: number): T | undefined {\n return this.items.find(item => item.id === id);\n }\n}\n\n// उपयोग\ninterface Product {\n id: number;\n title: string;\n price: number;\n}\n\nconst productRepo = new Repository<Product>();\nproductRepo.add({ id: 1, title: 'लैपटॉप', price: 1000 });\nconst laptop = productRepo.getById(1);\n\n\nएरर हैंडलिंग के लिए रैपर
\n\nएक सामान्य फंक्शन जो एरर को हैंडल करता है: