What is covariance and contravariance in TypeScript?
Why Interviewers Ask This
This tests whether you can apply TypeScript knowledge to real-world scenarios. Interviewers are looking for clarity of thought and evidence that you've encountered this in production code.
Answer
Variance describes how subtyping relationships between complex types relate to subtyping of their component types. In TypeScript: Covariance means "subtype in, subtype out" — if Cat is a subtype of Animal, then Array<Cat> is a subtype of Array<Animal> (you can use a Cat array where an Animal array is expected). Most positions in TypeScript are covariant. Contravariance means the direction is reversed — if Cat extends Animal, a function (a: Animal) => void is a subtype of (c: Cat) => void. This is because a function that can handle any Animal can certainly handle a Cat, but not vice versa. TypeScript enforces contravariance for function parameters with "strictFunctionTypes": true. This matters for callbacks and event handlers — a more general callback is safely substitutable for a more specific one. Methods (unlike function properties) are bivariant in TypeScript for historical compatibility reasons.
Pro Tip
Before answering, structure your response: one-line definition → real-world analogy → concrete example from a project. This makes even complex TypeScript answers easy to follow.
Previous
What is the Awaited utility type in TypeScript?
Next
What is a type predicate in TypeScript?