आप टाइप narrowing की व्यवस्थाओं में महारत हासिल करते हैं और unions को अधिक भरोसेमंद बनाने के लिए अपने खुद के predicates लिखते हैं।
इस पाठ को Kodokon में खोलेंNarrowing वह व्यवस्था है जिसके ज़रिए TypeScript नियंत्रण-प्रवाह (control flow) का विश्लेषण करके किसी व्यापक टाइप (एक union, unknown) को अधिक सटीक टाइप में परिष्कृत करता है। आप इसे बिना सोचे-समझे पहले से ही इस्तेमाल करते हैं: किसी typed मान पर लगाया गया हर if एक विश्लेषण को सक्रिय करता है। कंपाइलर तीन प्रकार के अंतर्निर्मित guards को ट्रैक करता है: primitives के लिए typeof, class instances के लिए instanceof, और किसी property की मौजूदगी के लिए in। इन्हें सही ढंग से चुनना आपको as के साथ की जाने वाली लापरवाह casts से बचाता है, जो सत्यापन का मार्गदर्शन करने के बजाय उसे बंद कर देती हैं।
function formatValue(
value: string | number | Date
): string {
if (typeof value === "string") {
return value.trim();
}
if (value instanceof Date) {
return value.toISOString();
}
return value.toFixed(2);
}in ऑपरेटर तब अमूल्य होता है जब आप संरचनात्मक रूप से भिन्न ऐसे objects को संभालते हैं जिनमें कोई discriminant फ़ील्ड नहीं होती। लेकिन सावधान रहें: in किसी key की मौजूदगी की जाँच करता है, जिसमें विरासत में मिली (inherited) keys भी शामिल हैं, न कि उसके टाइप की। बाहरी डेटा (APIs, JSON) पर, यह आपकी घोषणाओं के अनुसार narrow करता है, न कि रनटाइम पर वास्तव में जो मौजूद है उसके अनुसार। एक क्लासिक वास्तविक-जगत का जाल: typeof value === "object" की जाँच null को गुज़र जाने देती है, क्योंकि JavaScript में typeof null का मान "object" होता है। हमेशा एक स्पष्ट null जाँच जोड़ें।
interface Cat { meow(): void }
interface Dog { bark(): void }
function speak(animal: Cat | Dog): void {
if ("meow" in animal) {
animal.meow();
} else {
animal.bark();
}
}जब guard का तर्क पुनः प्रयोग करने योग्य हो जाए या flow विश्लेषण के लिए बहुत जटिल हो जाए, तो एक custom type guard लिखें: एक ऐसा function जिसका return टाइप value is T के रूप में annotate किया गया हो। तब कंपाइलर आपके implementation पर भरोसा करता है। यह एक अनुबंध है: यदि आपकी जाँच अधूरी है, तो आप रनटाइम errors को फिर से ले आते हैं जिन्हें टाइप सिस्टम कभी नहीं देख पाएगा। TypeScript 5.5 से, filter जैसे callbacks में सरल predicates अपने-आप infer हो जाते हैं, लेकिन exported functions के लिए स्पष्ट annotation अब भी मानक है।
interface User { id: string; email: string }
function isUser(value: unknown): value is User {
return (
typeof value === "object" &&
value !== null &&
"id" in value &&
typeof value.id === "string" &&
"email" in value &&
typeof value.email === "string"
);
}
const raw: unknown =
JSON.parse('{"id":"1","email":"a@b.c"}');
if (isUser(raw)) {
console.log(raw.email.toLowerCase());
}typeof value === "object" की जाँच पर्याप्त क्यों नहीं है?booleanvalue as Uservalue is Userasserts value