Typescript's type system uses structural subtyping and hence allows every data structure for a given type that contains at least the demanded properties.
However, we can easily restrict this less safe polymorphism to row polymorphism by utilizing generics:
type foo = { first: string, last: string };
const o = { first: "Foo", last: "Oof", age: 30 };
const p = { first: "Bar", last: "Rab", age: 45 };
const q = { first: "Baz", last: "Zab", gender: "m" };
const main = <T extends foo>(o: T) => (p: T) => o.first + o.last
main(o) (p); // type checks
main(o) (q); // type error
This isn't as type safe as nominal typing but definitively an improvement. Read more in chapter A Little Type Theory of the FP in JS course.
Top comments (2)
I can't quite see why the second example doesn't type check?
Oh now I see it, both T's have to be the same shape.