Back
Syntax
Study
Editor
Mode:
HTML
CSS
JavaScript
PHP
Reset
Run »
HTML / CSS / JS
// Covariance — return types type Producer<T> = () => T; // Dog is a subtype of Animal class Animal { name: string = "animal" } class Dog extends Animal { breed: string = "lab" } // Producer<Dog> is assignable to Producer<Animal> (covariant) const dogProducer: Producer<Dog> = () => new Dog(); const animalProducer: Producer<Animal> = dogProducer; // OK // Contravariance — parameter types type Consumer<T> = (value: T) => void; // Consumer<Animal> is assignable to Consumer<Dog> (contravariant) const animalConsumer: Consumer<Animal> = (a) => console.log(a.name); const dogConsumer: Consumer<Dog> = animalConsumer; // OK — handles more than needed // Explicit variance annotations (TypeScript 4.7+) type CovariantBox<out T> = { get(): T }; type ContravariantBox<in T> = { set(value: T): void }; type InvariantBox<T> = { get(): T; set(value: T): void }; // CovariantBox<Dog> extends CovariantBox<Animal> const dogBox: CovariantBox<Dog> = { get: () => new Dog() }; const animalBox: CovariantBox<Animal> = dogBox; // OK // Method vs function property — different variance interface WithMethod { method(s: string): void } // bivariant (unsound) interface WithProperty { prop: (s: string) => void } // contravariant (sound) // Readonly arrays are covariant, mutable arrays are not const dogs: Dog[] = [new Dog()]; const animals: readonly Animal[] = dogs; // OK (readonly covariance) // const mutableAnimals: Animal[] = dogs; // Error in strict mode
Result
Open