Variacija aprašo, kaip sudėtinio tipo subtipizavimas susijęs su jo dalių subtipizavimu — t. y. kada Container<Sub> yra priskirti Container<Super>?
Tegul Dog būna Animal poaibis.
let dogs: Dog[] = [];
let animals: Animal[] = dogs; // ✅ Dog[] is assignable to Animal[]
Grąžinimo tipai ir masyvai yra kovariantūs: jei Dog ⊆ Animal, tada Dog[] ⊆ Animal[]. Funkcija, grąžinanti Dog, gali būti naudojama ten, kur tikimasi tos, kuri grąžina 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
Funkcijų parametrai yra kontravariantūs: Handler<Animal> gali būti priskirti Handler<Dog>, priešinga elemento santykio kryptis. Tai yra saugus — kažkas, kas tvarko visus gyvūnus, tikrai gali tvarkyti šunis.
// Method parameters in TS are bivariant by default (a known unsound convenience)
interface Comparer<T> { compare(a: T): void; }
TypeScript tikrina atskiros funkcijos tipus kontravariantiškai tik su strictFunctionTypes; metodų parametrai yra namomis skirtas bivariantūs ergonomikos dėlei, kas techniškai nėra saugus.
Variacija paaiškina, kodėl tam tikri priskyrimai yra leisti arba atmeti — kodėl Dog[] tinka Animal[], bet grąžinimo tipo (d: Dog) => void grąžinimas ne visada gali pakeisti (a: Animal) => void.
Supratimas padeda jums kurti bendrintus API (pvz. tik skaitomiems ir rašomoms pozicijoms) ir iššifruoti painius "negalima priskirti" klaidų pranešimus, susijusius su funkcijomis ir bendrintais tipais.