Use of Mapping Types in TypeScript
I’ve been reading up on my #Typescript and one feature that is under used is mapping types and using them to create new types.
On some codebases I’ve worked on I’ve seen, and have been guilty of myself, creating new type definitions that maybe extend another Type or are extremely close. For example, a User type and a Staff type both have similar properties (firstname, lastname, email, id etc)
type User = { id,firstname, lastname, email};
type Staff = {id, firstname, lastname, email, jobtitle);
In the need to get a new feature completed it can be quiet easy to create a new Type definition without checking to see if there is something that is already within the code that can be used or extended. Creating new types as we go can lead to cases like above where two types have been created, the original User
type and the quickly written Staff
type that is needed in a function of a component I’m developing as part of that feature that needs to be done, and I know that I will go back and refactor the code to use an extended or mapped type when I have time (which we all know, we never do).
This is where I feel in my own code mapping types should be used. With a mapping I can create my new type, and if for some reason (API changes or another developer changes the original definition) the remapping of my new type is updated if the original type is changed. So in the case of our User
and Staff
types if there is a change to the API and title is added as a property which needs to also be displayed in a screen that is making use of the Staff type. By using a Mapped type, this new property is automatically available.
I feel this makes the code more robust and flexible to change, the issue with mapping types is that the syntax is not as clear as using the extends keyword, but really all we are doing in a mapped type is looping over another key and picking what we want from it to create a new type and if that original type changes our derived mapped type can be amended too without to much work.
I think the main aim for how I should write my TypeScript code is to think what are the main data structures in an app, maybe defined by what an API is returning me or what I’m asking for if using GraphQL, and how can set up all the other Types in my application to be created or inferred from these base Types. So my code is both type safe but also flexible enough to handle changes over time. (I think this is the main message Matt Pocock has been trying to get across in his courses and book).