Bambanta yana bayyana yadda subtyping na nau'in hadada ya danganta da subtyping na sigar sa — watau, lokacin da Container<Sub> za a iya saita ga Container<Super>?
Bari Dog su zama wani subtype na Animal.
let dogs: Dog[] = [];
let animals: Animal[] = dogs; // ✅ Dog[] is assignable to Animal[]
Jitawa da jeri suna haɗa da covariance: idan Dog ⊆ Animal, to Dog[] ⊆ Animal[]. Aiki na jita Dog ana iya amfani dashi a waje an tsammani Animal jita.
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
Aiki sigogi suna contravariance: Handler<Animal> ana iya saita ga Handler<Dog>, maimakon dangantaka siga. Wannan yana da izini — abin da ke kulawar duk dabbobi tabbas yana kulawa da karnuka.
// Method parameters in TS are bivariant by default (a known unsound convenience)
interface Comparer<T> { compare(a: T): void; }
TypeScript yana bincika nau'ikan aiki na kada-juna da contravariance kawai a ƙarƙashin strictFunctionTypes; sigogin hanyar aiki an shirya su bivariant saboda ergonomics, wanda bisa gida ba shi da izini.
Bambanta ya bayyana menene da yasa wasu alokacin suna yarda ko ba ba — menene da yasa Dog[] ya dace da Animal[] amma callback na (d: Dog) => void ba yana iya tsaya a madadin (a: Animal) => void koyaushe.
Sanin sa yana taimaka muku wajen tsara APIs na jeli (misali kamar karanta-kawai da wuri na rubuta) da code rikurori na rikurori na "ba a iya saita" waɗanda suka haɗa aiki da jeli.