3 ms·
I think that interfaces in TypeScript unfortunately contribute to that confusion. I can do interface Point2D { x: number y: number } And then I ca
by LudwigNagasena 4y ago
I think that interfaces in TypeScript unfortunately contribute to that confusion. I can do
interface Point2D {
x: number
y: number
}
And then I can do
interface Point3D extends Point2D {
z: number
}
And that "extends" really throws off many people because in reality the type of Point2D is implicitly
{
x: number
y: number
[anything_else in string]: unknown
}
So Point3D actually narrows the type of Point2D even though the notation suggests that it widens it. Fortunately, the type notation is less misleading because I can do
type Point3D = Point2D & {
z: number
}
Without any misleading "extensions".
It seems like it all stems from the tight coupling between types and classes in a typical OOP paradigm. When you create a class Animal you create a type Animal that should conform to specific rules, but when you instantiate that class you create an object that conforms to a narrower set of rules. E.g. an object instantiated from class Animal won't be able to woof() even though the type "Animal" easily allows it. This leads to the mental model of "extending" base class with new fields and methods. And even though it indeed extends the class Animal, it narrows the type Animal.
- dragonwriter 4y ago> So Point3D actually narrows the type of Point2D even though the notation suggests that it widens it. The notation suggests that it extends the definition with additional restrictions. Which it does. Which, yes, produces a narrower scope. That’s how definitions work.
- LudwigNagasena 4y agoIn mathematical logic, for example, saying that A is an elementary substructure of B is equivalent to saying that B is an elementary extension of A. The same with subfields and extension fields. Those concepts are opposite. Usually in OOP you extend a class with additional implementation. Intersection of types means union of their members and vice versa. Getting into a situation where extending X gives you a sub-X seems like an unfortunate case of mixing two mental models that behave in a dual manner.
- goto11 4y ago"Extends" does not mean it extends the type to contain more members, it means it extends instances to have more properties, thereby creating a subset or subtype. Perhaps it is confusing that TypeScript uses terms from both set-theory (union, intersection) and OO (extends, implements). But there is no contradiction.
- LudwigNagasena 4y agoRight, my point is that it is confusing.