TypeScript में मिलती-जुलती टाइप घोषणाएँ दोहरें तो इनपुट टाइप से परिणाम निकालने का तरीका खोजते हैं। अक्षर घटने से ज्यादा जरूरी है कि पाठक को टाइपों का संबंध स्पष्ट हो। काल्पनिक डिलीवरी सूचना सेवा से कंडिशनल टाइप और infer समझेंगे और बाहरी डेटा वास्तव में सही होने की जाँच से इन्हें अलग करेंगे।
1. कंडिशनल टाइप, टाइप इनपुट वाली शाखा है
आधिकारिक कंडिशनल टाइप दस्तावेज extends की शर्त से परिणाम टाइप चुनने का व्याकरण बताते हैं। उदाहरण स्ट्रिंग टाइप होने के अनुसार बूलियन लिटरल टाइप बनाता है। यह चलते प्रोग्राम में स्ट्रिंग जाँचने वाला फंक्शन नहीं है।
type IsText<T> = T extends string ? true : false;
type NameIsText = IsText<'parcel'>; // true
type CountIsText = IsText<3>; // false
मानें डिलीवरी सूचना बनाने वाला फंक्शन स्ट्रिंग पहचानकर्ता लेता है और अंदर का प्रोसेसिंग फंक्शन संख्या पहचानकर्ता। कंडिशनल टाइप से पहले बता सकें कि दोनों अलग क्यों हैं। अर्थ अलग हो तो अलग नाम सहायक हैं; केवल लिखावट का फर्क हो तो समान इनपुट प्रारूप ज्यादा पठनीय हो सकता है। टाइप तकनीक से डेटा डिजाइन की अस्पष्टता न छिपाएँ।
समीक्षा में अपेक्षित इनपुट और परिणाम जोड़े में लिखें। स्ट्रिंग, संख्या, यूनियन और अप्रत्याशित इनपुट को छोटे उदाहरणों में बाँटने से जटिल घोषणा पढ़ना आसान होता है। टिप्पणी का परिणाम और एडिटर का अनुमानित टाइप मिलते हैं या नहीं जाँचें। नाम सहज लगने पर भी असली गणना अलग हो सकती है।
2. यूनियन वितरण ऐरे का अर्थ बदलता है
टाइप पैरामीटर सीधे शर्त के बाएँ हो तो हर यूनियन सदस्य पर शर्त लागू होती है। वितरण रोककर पूरी यूनियन को एक मानने के लिए चौकोर ब्रैकेट में लिपटे रूप की तुलना करें।
type SeparateLists<T> = T extends unknown ? T[] : never;
type Together<T> = [T] extends [unknown] ? T[] : never;
type A = SeparateLists<string | number>; // string[] | number[]
type B = Together<string | number>; // (string | number)[]
const a: A = ['a', 'b'];
const b: B = ['a', 1];
पहला केवल स्ट्रिंगों वाला या केवल संख्याओं वाला ऐरे है। दूसरे में एक ऐरे में दोनों हो सकते हैं। पूरी डिलीवरी सूची में एक तरह का कोड चाहिए या हर मद में अलग तरह स्वीकार है, इससे उचित परिणाम बदलता है। दोनों में ब्रैकेट दिखते हैं, पर अनुबंध समान नहीं।
व्यावहारिक समस्या पर पूरी जटिल यूटिलिटी एक बार पढ़ने के बजाय एक-एक सदस्य इनपुट दें। स्ट्रिंग, संख्या और दोनों की यूनियन के परिणाम तुलना करें। वितरण जानबूझकर था या नहीं स्पष्ट हो तो ब्रैकेट जोड़ने का कारण भी बता सकते हैं। समीक्षा रिकॉर्ड में अंतिम परिणाम के साथ स्वीकार्य मानों के उदाहरण भी रखें।
3. infer संरचना के भीतर के टाइप को नाम देता है
कंडिशनल टाइप में infer मिलाई गई संरचना के एक भाग को नाम देने के काम आता है। यह छोटा उदाहरण Promise की एक परत हटाता है।
type OneResult<T> = T extends Promise<infer Value> ? Value : T;
type Parcel = OneResult<Promise<{ tracking: string }>>;
type ParcelList = OneResult<Promise<string[]>>;
कोड एसिंक्रोनस काम न चलाता है न उसकी प्रतीक्षा करता है। यह केवल संकलन के समय परिणाम का रूप बताता है। Resolved जैसा नाम लगे तो मान पहले ही आ गया होने का आभास हो सकता है, इसलिए उपयोग का संदर्भ देखें। चलते समय प्रतीक्षा अब भी एसिंक्रोनस कोड में संभालनी होगी।
पुनरावर्ती प्रतीक्षा का परिणाम टाइप चाहिए तो एक-परत वाले शैक्षिक उदाहरण को बढ़ाते जाने से पहले मानक यूटिलिटी Awaited देखें। शैक्षिक सरलता और साझा उपकरण की जरूरतें अलग हैं। टीम में नई यूटिलिटी लाएँ तो मानक से अलग परिणाम देने वाले इनपुट और फर्क की जरूरत दस्तावेजित करें।
4. टेम्पलेट लिटरल से इवेंट नाम जोड़ें
टेम्पलेट लिटरल टाइप स्ट्रिंग लिटरल के संयोजन को टाइप में दिखाते हैं। डिलीवरी सेवा में क्षेत्र और क्रिया से बने इवेंट नाम उदाहरण हैं।
type Scope = 'parcel' | 'address';
type Action = 'created' | 'updated';
type EventName = `${Scope}:${Action}`;
const event: EventName = 'parcel:created';
गलत वर्तनी संकलन में मिल सकती है, लेकिन हर संभव संयोजन असली सेवा में वैध है या नहीं, अलग प्रश्न है। केवल पता हटाने का इवेंट समर्थित हो तो क्षेत्र और क्रिया का सरल गुणन नियम ठीक से नहीं व्यक्त कर सकता। पहले अनुमत इवेंट और payload का स्पष्ट मानचित्र सोचें।
इवेंट बढ़ने पर पाठक असली नाम आसानी से खोज पाता है या नहीं, यह भी अहम है। स्वचालित संयोजन के कई स्तर जोड़ने के बजाय बाहरी सिस्टम को दिए नाम एक फाइल में दिखाए जा सकते हैं। अमूर्तन से पहले और बाद नया सदस्य गलत इवेंट कैसे पकड़ेगा, तुलना करें। टाइप की सटीकता और उपयोगिता दोनों परखें।
5. बाहरी JSON चलते समय जाँचना होगा
API उत्तर को User या Parcel टाइप लिख देने से असली उत्तर उसी संरचना का होने की गारंटी नहीं। बाहरी मान unknown लेकर जरूरी फील्ड जाँचने का सरल तरीका देखें।
function hasTracking(value: unknown): value is { tracking: string } {
return typeof value === 'object' && value !== null
&& 'tracking' in value && typeof value.tracking === 'string';
}
const incoming: unknown = { tracking: 'DEMO-001' };
if (hasTracking(incoming)) console.log(incoming.tracking);
जाँच केवल tracking का स्ट्रिंग होना बताती है। वह ट्रैकिंग संख्या सचमुच मौजूद है या उपयोगकर्ता को डिलीवरी देखने का अधिकार है, यह नहीं। टाइप नैरोइंग, व्यावसायिक नियम और अधिकार जाँच अलग जिम्मेदारियाँ हैं। आधिकारिक Narrowing दस्तावेज शर्तों से टाइप सूचना संकरी होने की प्रक्रिया बताते हैं।
6. टाइप उपकरण चुनने का छोटा क्रम
पहले दो स्वीकार्य और दो अस्वीकार्य वास्तविक मान लिखें। फिर साधारण यूनियन और स्पष्ट ऑब्जेक्ट घोषणा से अर्थ व्यक्त करें। दोहरते संबंध बचें तब कंडिशनल टाइप या infer का कारण स्पष्ट होगा। घोषणा पढ़ने का समय बहुत बढ़े तो केवल साझा भाग निकालकर शेष सामान्य टाइप रहने देना भी संभव है।
अंत में टाइप जाँच और रनटाइम जाँच अलग चलाएँ। गलत इवेंट नाम को कंपाइलर ठुकराता है या नहीं देखना और सर्वर फील्ड छोड़ दे तब प्रोग्राम त्रुटि समझाता है या नहीं देखना एक-दूसरे के पूरक हैं। छोटे उदाहरण जाँचकर वास्तविक इनपुट सीमा तक जोड़ने पर ही टाइप रूपांतरण सुरक्षित एप्लिकेशन डिजाइन में सहायक होता है।