4 ms·
You are getting close! It is both. So here the LSP violation being described is that a function which handles a Rectangle it is given properly (i.e. it does no
by crdrost 6y ago
You are getting close! It is both. So here the LSP violation being described is that a function which handles a Rectangle it is given properly (i.e. it does not construct it) might fail when given a subclass of Rectangle, precisely due to OOP fundamentals about late binding and letting the runtime class drive the runtime behavior. But your hunch that subtypes widen "capabilities" is also formally correct: if P is a subtype of Q then we expect that the function type P → X for arbitrary X is a supertype of Q → X. So if you have like a list of squares and you want to map over it, map requests a Square → X function but we understand intuitively that you should always be able to provide a Rectangle → X function in this argument slot, too.
This is not just abstract... I forget where in the docs TypeScript starts talking about certain things being incorrect because other things are not contravariant/covariant/invariant, but yeah: TypeScript is trying to implement a practical subtyping system and technically subclasses are not subtypes of their parent classes in TypeScript’s original vision, so pragmatism forces you to say “just pretend they are!” and technically the subtype system is unsound.
The problem is that in TypeScript’s theory a type is just the full interface of object properties on a value, including all their methods. Methods always look like functions with an implicit "this" argument type. So this becomes a problem precisely because the type of Rectangle looks like
type Rectangle = {
height: number,
width: number,
someMethod: (this: Rectangle) => something
}
And that recursive definition in terms of having those methods makes a type technically terminal (no subtypes can exist).
So it is precisely that we can overload methods with implementations more specific to the subtype, which stops the subclass from being a subtype of the superclass.