Summary - Variance
- TypeScript course
- Advanced
- Lesson 16/57
- 4 min
Write a program comparing variance rules.
Summary - Variance
Variance rules describe how a subtype relationship propagates to function types. Covariance keeps the relationship in the same direction (return type, arrays). Contravariance reverses it (parameter type, under strictFunctionTypes). Bivariance accepts both directions (method shorthand or strict off).
class Animal {}
class Dog extends Animal {}
// Covariance (return type):
const a: () => Animal = () => new Dog();
// Contravariance (parameter, under strict):
const b: (d: Dog) => void = (x: Animal) => {};
// Bivariance (method shorthand):
interface Kennel { keep(d: Dog): void; }
const k: Kennel = { keep(x: Animal) {} };Practice Show all three rules in one program
Define a Dog class extending Animal. Show three things: (1) Covariance: assign a () => Dog function to a () => Animal type and print the name of the returned object. (2) Contravariance: assign a (a: Animal) => void function to a (d: Dog) => void type. (3) Bivariance: write a Kennel interface with a keep(d: Dog): void method and implement it as keep(a: Animal) {}. Print the labels "covariance", "contravariance", "bivariance" via console.log before each section.
Starter code
class Animal {
name = "animal";
}
// Dog sınıfını tanımla
// 1) Covariance: () => Dog -> () => Animal
// 2) Contravariance: (a: Animal) => void -> (d: Dog) => void
// 3) Bivariance: Kennel interface ve implementationSample solution
class Animal {
name = "animal";
}
class Dog extends Animal {}
console.log("covariance");
const makeAnimal: () => Animal = () => new Dog();
console.log(makeAnimal().name);
console.log("contravariance");
const dogHandler: (d: Dog) => void = (a: Animal) => {};
dogHandler(new Dog());
console.log("bivariance");
interface Kennel {
keep(d: Dog): void;
}
const k: Kennel = {
keep(a: Animal) {}
};
k.keep(new Dog());Expected output
covariance animal contravariance bivariance
Questions and answers
Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.
1 How is the return type checked in a function type (with strictFunctionTypes on)?
- Invariant
- Contravariant
- Covariant Correct answer
- Bivariant
Explanation: The return type is always checked covariantly; a function returning a subtype is assignable where a supertype return is expected.
2 Which type for a contravariant parameter
class Animal {}
class Dog extends Animal {}
// Contravariance örneği: h, Dog beklerken implementation Animal kabul eder
const h: (d: Dog) => void = (x: ____) => {};
class Animal {}
class Dog extends Animal {}
// Contravariance örneği: h, Dog beklerken implementation Animal kabul eder
const h: (d: Dog) => void = (x: Animal) => {};
Explanation: For contravariance the parameter must be a supertype of the target's parameter; Animal is the supertype of Dog, so it is correct.
3 Variance rules matching
| Term | Meaning |
|---|---|
Dönüş türü |
Covariance |
Parametre (strict altında) |
Contravariance |
Method shorthand |
Bivariance |
Dog döndüren fonksiyon |
assignable to Animal-returning expectation |