In part 1 of this series we developed an API for searching and sorting HTML tables. We introduced some code reuse in part 2 but were dissatisfied with the boilerplate. Part 3 teased us with
keyof, a promising feature of the type system. In this final post we dig in and finally deliver the goods.
Mapped, Conditional Types
TypeScript provides the ability to transform a type into another type using a mapping operation. Imagine we want to create a version of our
Person type where all the fields are read-only:
With that, you can tell the compiler to take an instance of the Person class
And treat it as though it was written this way:
Pretty cool trick if you decide to introduce immutability to an existing API, for example.
Conditions can be applied to types during mapping. Here we create a type that contains only the string fields on Person:
map k -> k if Person[k] is a string, otherwise map k -> never, which is a type that matches nothing.
'age' from the union. This is exactly what we need.
The Final Version
First we add some type aliases that are easier to digest than the raw definitions.
And fix the hole in the TableSort API.
The compiler now prevents us from doing the wrong thing and code completion guides us to the right thing. Adding the
Yields this table configuration code
And this code refreshes the display
TypeScript – A Good Part
How Excellence Happens
My teammate Patrick and I never set out to solve this problem together. We were independently driven to rid the code of some repetitive boilerplate. Along the way, we discussed some ideas and agreed that, while our respective ideas had merit, none were satisfying. We kept up our other work, but poked at this problem along the way. And we came up with something better than either of us could have done alone. We both discovered something new, and I had a $5 beer. For me, this kind of experience brings the most joy, and I am grateful to Patrick for having the enthusiasm and desire to challenge my work, to make our software better, together.