TypeScript में Generics का परिचय
TypeScript एक सख्ती से टाइप की जाने वाली भाषा है, जो JavaScript की क्षमताओं को स्थिर टाइपिंग जोड़कर बढ़ाती है। हालांकि, इसकी सबसे शक्तिशाली और लचीली विशेषताओं में से एक Generics (जेनेरिक्स) तंत्र है। यदि आपने कभी ऐसा कोड लिखा है जो विभिन्न डेटा प्रकारों के साथ काम करता हो, लेकिन टाइप सुरक्षा बनाए रखता हो, तो Generics आपके लिए ही हैं।
कल्पना करें कि आप एक सार्वभौमिक फ़ंक्शन बना रहे हैं जो संख्याओं, स्ट्रिंग्स या ऑब्जेक्ट्स की arrays को स्वीकार कर सके। जेनेरिक्स के बिना, आपको या तो any टाइप का उपयोग करना होगा (जो TypeScript के सभी लाभों को समाप्त कर देता है), या प्रत्येक प्रकार के लिए अलग-अलग फ़ंक्शन लिखने होंगे। Generics इस समस्या को सुरुचिपूर्ण और सुरक्षित तरीके से हल करते हैं। इस लेख में, हम जानेंगे कि Generics क्या हैं, उनकी आवश्यकता क्यों है, और वास्तविक प्रोजेक्ट्स में उनका प्रभावी ढंग से उपयोग कैसे करें।
Generics क्या हैं और उनकी आवश्यकता क्यों है?
Generics एक ऐसा तंत्र है जो आपको ऐसे घटक (फ़ंक्शन, क्लास, इंटरफ़ेस) बनाने की अनुमति देता है जो विभिन्न डेटा प्रकारों के साथ काम कर सकें, बिना प्रकारों के बारे में जानकारी खोए। किसी विशिष्ट प्रकार को निर्धारित करने के बजाय, आप एक टाइप पैरामीटर का उपयोग करते हैं, जो कॉल के समय प्रतिस्थापित हो जाता है।
Generics के बिना समस्या
मान लीजिए आप एक ऐसा फ़ंक्शन लिखना चाहते हैं जो किसी array का पहला एलिमेंट लौटाता है। जेनेरिक्स के बिना यह इस तरह दिख सकता है:
function getFirstElement(arr: any[]): any { return arr[0];}
const num = getFirstElement([1, 2, 3]); // टाइप 'any' — हमने जानकारी खो दीconsole.log(num.toUpperCase()); // रनटाइम पर त्रुटि, लेकिन TypeScript चुप हैयहां हम any का उपयोग कर रहे हैं, और TypeScript हमें यह चेतावनी नहीं दे सकता कि num एक संख्या है, स्ट्रिंग नहीं। इससे रनटाइम पर संभावित त्रुटियां होती हैं।
Generics के साथ समाधान
अब उसी फ़ंक्शन को जेनेरिक्स का उपयोग करके फिर से लिखते हैं:
function getFirstElement<T>(arr: T[]): T { return arr[0];}
const num = getFirstElement([1, 2, 3]); // टाइप 'number'const str = getFirstElement(['a', 'b', 'c']); // टाइप 'string'
// num.toUpperCase(); // कम्पाइलेशन त्रुटि — TypeScript जानता है कि num एक संख्या हैप्रतीक <T> एक टाइप पैरामीटर है। यह एक placeholder की तरह काम करता है: जब हम फ़ंक्शन को संख्याओं की array के साथ कॉल करते हैं, तो T number बन जाता है, और रिटर्न वैल्यू भी number टाइप प्राप्त करती है। इस प्रकार, हम लचीलापन खोए बिना सख्त टाइपिंग बनाए रखते हैं।
Generics का उपयोग कैसे करें: मुख्य परिदृश्य
Generics केवल फ़ंक्शन में ही नहीं, बल्कि क्लास, इंटरफ़ेस और टाइप में भी लागू होते हैं। आइए सबसे सामान्य परिदृश्यों पर नज़र डालें।
फ़ंक्शन में Generics
सबसे सरल और सामान्य मामला वे फ़ंक्शन हैं जो विभिन्न प्रकारों के डेटा के साथ काम करते हैं। उदाहरण के लिए, key-value जोड़ी बनाने का फ़ंक्शन:
function createPair<K, V>(key: K, value: V): { key: K; value: V } { return { key, value };}
const pair = createPair('id', 123); // { key: string; value: number }console.log(pair.key.toUpperCase()); // काम करता है// pair.key.toFixed(); // त्रुटि — key एक स्ट्रिंग हैयहां हम दो टाइप पैरामीटर का उपयोग कर रहे हैं: key के लिए K और value के लिए V। TypeScript तर्कों के आधार पर स्वचालित रूप से प्रकारों का अनुमान लगाता है।
क्लास में Generics
जेनेरिक्स सार्वभौमिक क्लास बनाने के लिए उत्कृष्ट हैं, जैसे स्टैक, क्यू या डेटा स्टोर:
class Stack<T> { private items: T[] = [];
push(item: T): void { this.items.push(item); }
pop(): T | undefined { return this.items.pop(); }
peek(): T | undefined { return this.items[this.items.length - 1]; }}
const numberStack = new Stack<number>();numberStack.push(10);numberStack.push(20);console.log(numberStack
```