TypeScript Covariance and Contravariance

I want to share a small part of wikipedia description firstly then will continue with example codes.

Assume that we work with below types.

Animal is Supertype.

Dog and Cat are Subtype.


Covariance means that Subtypes can be assigned to Supertypes. This is also known as Polymorphism or Subtyping. So Covariance = Polymorphism = Subtyping

In other words, Dog(Subtype) can be assigned to Animal(Subtype) or Dog(Subtype)

Generic types are also covariant.


Function's parameters are covariant so it mean that when we need to assign a function to a variable, right side of assignment should be Supertype and right side of assignment should be Subtype.

Notice that variable type of a5 in below screenshot is a function which accepts Dog(Subtype of Animal) parameter and returns Animal(Supertype) but when assigning a function which accepts Animal(Supertype) parameter and returns Animal. Strange part is here instead of Subtyping, function's parameter accepts Supertype.

When we call getAnimalInfo with a Supertype Dog, the implementation of getAnimalInfo function accepts Supertype Animal so it can reach only Animal fields and functions(behaviours) not Subtype behaviours like bark() function in Dog.

const getAnimalInfo: (p: Dog) => string = (p: Animal) => {

    return p.name;

getAnimalInfo(new Dog("Markus"));

Leave a Reply