0
0
Typescriptprogramming~10 mins

Covariance and contravariance in Typescript - Step-by-Step Execution

Choose your learning style9 modes available
Concept Flow - Covariance and contravariance
Start with types
Check assignment compatibility
Covariance: output types compatible?
YesAllow assignment
Error
Contravariance: input types compatible?
YesAllow assignment
No
Error
This flow shows how TypeScript checks if one type can be assigned to another by comparing output types (covariance) and input types (contravariance).
Execution Sample
Typescript
interface Animal { name: string }
interface Dog extends Animal { bark(): void }

let dogFunc: (d: Dog) => Dog;
let animalFunc: (a: Animal) => Animal;

animalFunc = dogFunc; // Contravariance check

dogFunc = animalFunc; // Covariance check
This code tests assigning functions with parameters and return types to see covariance and contravariance in action.
Execution Table
StepActionInput Type CheckOutput Type CheckAssignment AllowedReason
1Assign dogFunc to animalFuncDog parameter to Animal parameter?Dog return to Animal return?YesParameter types must be contravariant (Animal assignable to Dog), and Dog is assignable to Animal for return types
2Assign animalFunc to dogFuncAnimal parameter to Dog parameter?Animal return to Dog return?NoParameter types must be contravariant (Dog not assignable to Animal), or return types must be covariant (Animal not assignable to Dog)
3Assign compatible function typesParameter types contravariantReturn types covariantYesBoth input and output types satisfy variance rules
4End---No more assignments to check
💡 Assignments stop when type compatibility rules fail or all checks pass
Variable Tracker
VariableStartAfter Step 1After Step 2After Step 3Final
dogFuncfunction (Dog) => Dogunchangedunchangedassigned animalFunc if compatiblefinal assigned value
animalFuncfunction (Animal) => Animalassigned dogFuncunchangedunchangedfinal assigned value
Key Moments - 2 Insights
Why can't we assign a function with parameter type Dog to a variable expecting a function with parameter type Animal?
Because function parameters are contravariant, the assigned function must accept all inputs the variable expects. A Dog parameter is more specific than Animal, so it can't accept all Animals. See execution_table step 2.
Why can't we assign a function returning Animal to a variable expecting a function returning Dog?
Because return types are covariant, the assigned function must return a type compatible with the variable's expected return. Animal is more general than Dog, so it may return something missing Dog's features. See execution_table step 2.
Visual Quiz - 3 Questions
Test your understanding
Look at the execution table, at which step is the assignment rejected due to parameter type incompatibility?
AStep 1
BStep 2
CStep 3
DStep 4
💡 Hint
Check the 'Input Type Check' and 'Assignment Allowed' columns in execution_table rows
According to variable_tracker, what is the state of dogFunc after step 2?
AUnchanged
BUndefined
CAssigned animalFunc
DNull
💡 Hint
Look at dogFunc row and After Step 2 column in variable_tracker
If we change Dog to extend Animal with no extra methods, how would step 2's output type check change?
ANo change, assignment rejected
BAssignment still rejected due to parameter types
CAssignment allowed because return types match
DAssignment allowed due to contravariance
💡 Hint
Consider covariance rules for return types in execution_table step 2
Concept Snapshot
Covariance and contravariance control function type assignments.
- Covariance: output (return) types can be more specific.
- Contravariance: input (parameter) types can be more general.
- TypeScript enforces these rules to keep assignments safe.
- Function parameters are contravariant; returns are covariant.
- Violations cause assignment errors.
Full Transcript
This visual execution shows how TypeScript checks function type assignments using covariance and contravariance. It starts by comparing input parameter types contravariantly and output return types covariantly. The execution table traces assignment attempts step-by-step, showing when assignments fail due to incompatible parameter or return types. The variable tracker records how function variables change or stay the same after each step. Key moments clarify why parameter types are contravariant and return types covariant, helping beginners avoid confusion. The quiz tests understanding by referencing the execution table and variable tracker. The snapshot summarizes the core rules for safe function type assignments in TypeScript.