Variance jiddeskriveix kif il-subtyping ta' tip kompost jirrileata mal-subtyping tal-partijiet tiegħu — jiġifieri meta Container<Sub> huwa assignable għal Container<Super>?
Khalli Dog ikun subtype ta' Animal.
let dogs: Dog[] = [];
let animals: Animal[] = dogs; // ✅ Dog[] is assignable to Animal[]
Return types u arrays huma covariant: jekk Dog ⊆ Animal, allura Dog[] ⊆ Animal[]. Funzjoni li terġa' Dog huwa utilisable fejn wieħed li jerġa' Animal huwa mistenni.
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
Function parameters huma contravariant: Handler<Animal> huwa assignable għal Handler<Dog>, il-reverse tal-relazzjoni tal-element. Dan huwa validu — xi ħadd li jikkuntentja l-annimali kollha ċertament jikkuntentja l-kanji.
// Method parameters in TS are bivariant by default (a known unsound convenience)
interface Comparer<T> { compare(a: T): void; }
TypeScript jivverifika l-funzjoni standalone types contravariantly biss taħt strictFunctionTypes; method parameters huma intenzjonalment bivariant għall-ergonomija, li teknegram mhux validu.
Variance tispjega għaliex ċerti assignments jintgħażlu jew jirifjutaw — għaliex Dog[] jiftu Animal[] imma callback (d: Dog) => void ma jistax dejjem jieqaf għal (a: Animal) => void.
Il-fehim tiegħu jgħinek tiddisinja generic APIs (eż. read-only kontra write positions) u tiddekodifika errors konfużi "not assignable" li jinvolvu functions u generics.