विचरण वर्णन करता है कि समग्र प्रकार का सबटाइपिंग इसके भागों के सबटाइपिंग से कैसे संबंधित है — अर्थात्, Container<Sub> को Container<Super> के लिए कब निर्दिष्ट किया जा सकता है?
Dog को Animal का एक उप-प्रकार माना जाए।
let dogs: Dog[] = [];
let animals: Animal[] = dogs; // ✅ Dog[] is assignable to Animal[]
वापसी प्रकार और सरणियां सहप्रसरण हैं: यदि Dog ⊆ Animal, तो Dog[] ⊆ Animal[]। एक फ़ंक्शन जो Dog लौटाता है, उस जगह पर उपयोग किया जा सकता है जहां Animal लौटाने की अपेक्षा है।
type Handler<T> = (arg: T) => void;
let animalHandler: Handler<Animal> = (a) => {};
let dogHandler: Handler<Dog> = animalHandler; // ✅ (with strictFunctionTypes)
// a handler that accepts ANY Animal can safely handle a Dog
फ़ंक्शन पैरामीटर प्रतिप्रसरणीय हैं: Handler<Animal> को Handler<Dog> के लिए निर्दिष्ट किया जा सकता है, जो तत्व संबंध का विपरीत है। यह सुरक्षित है — जो कुछ भी सभी जानवरों को संभालता है वह निश्चित रूप से कुत्तों को संभालता है।
// Method parameters in TS are bivariant by default (a known unsound convenience)
interface Comparer<T> { compare(a: T): void; }
TypeScript केवल strictFunctionTypes के तहत स्टैंडअलोन फ़ंक्शन प्रकारों को प्रतिप्रसरणीय रूप से जांचता है; विधि पैरामीटर ergonomics के लिए जानबूझकर द्विपरिवर्तनीय हैं, जो तकनीकी रूप से असुरक्षित है।
विचरण यह बताता है कि कुछ निर्दिष्ट करण क्यों अनुमत या अस्वीकृत हैं — Dog[] Animal[] के लिए क्यों फिट है लेकिन (d: Dog) => void कॉलबैक हमेशा (a: Animal) => void की जगह नहीं ले सकता।
इसे समझने से आप सामान्य API डिज़ाइन करने में मदद पाते हैं (जैसे केवल-पढ़ने बनाम लिखने की स्थितियां) और फ़ंक्शन और सामान्य से संबंधित भ्रमित "अनुदिष्ट नहीं" त्रुटियों को समझते हैं।