Issue
I have installed the newest version of TypeScript (4.2.4). Take this minimal example:
class Vehicle {
buildYear: number;
weight: number;
vehicleRegister: Map<string, (vehicle: Vehicle) => void>;
}
class Boat extends Vehicle {
name: string;
// boat register
vehicleRegister: Map<string, (vehicle: Boat) => void>; // error
}
As you can see, I am extending the Vehicle class with the Boat class and overriding the vehicleRegister
-property. However, doing it like this gives me the following error:
TS2416: Property 'vehicleRegister' in type 'Boat' is not assignable to the same property in base type 'Vehicle'.
Type 'Map<string, (vehicle: Boat) => void>' is not assignable to type 'Map<string, (vehicle: Vehicle) => void>'.
Type '(vehicle: Boat) => void' is not assignable to type '(vehicle: Vehicle) => void'.
Types of parameters 'vehicle' and 'vehicle' are incompatible.
Property 'name' is missing in type 'Vehicle' but required in type 'Boat'.
I do not understand why I cannot substitute the type of a base class with the type of a more specific class in the function argument of the callback function? Maybe I got the LSP wrong, but shouldn't every call to a function (vehicle: Boat) => void
also satisfy the contract established by the base type (vehicle: Vehicle) => void
? I feel like I'm completely thinking this wrong. I'm especially confused since the following code works:
class Vehicle {
buildYear: number;
weight: number;
vehicleRepository: Vehicle[];
}
class Boat extends Vehicle {
name: string;
vehicleRepository: Boat[]; // works
}
Thanks for any help!
Solution
Apparently, this has to do with function types being contravariant by their parameter types, meaning that having the more specific type in the parameter list does not mean that the function is a subtype of the function with the more general parameter type, but actually vice versa!
If anyone encounters the same issue, you can take a look here, for instance: https://dmitripavlutin.com/typescript-covariance-contravariance/
Answered By - Jonas Reinhardt
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.