Type indexing
One of the key principles when writing code is DRY - Don't Repeat Yourself.
In Typescript, one of the ways I found myself applying this principle is using type indexing.
Type indexing allows you to reference a piece of another type.
Let's take a look at an example:
1type User = { 2 id: string; 3 name: string; 4 age: number; 5} 6 7function findUser(userId: string) { ... }; 8function getUserProfilePhoto(userId: string) { ... };
In this example, we have a User type.
We're also using a piece of that type (the user ID) as an argument in the findUser
and getUserProfilePhoto
methods.
💡 The user ID is a string.
But what happens if, in the future, for whatever reason, I want to change it to a number?
I would have to update the type, but also find all instances where the user ID is referenced. This is not only a tidious job, but sometimes an impossible one.
Now, let's look at the same example, but with ✨type indexing✨:
1type User = { 2 id: string; 3 name: string; 4 age: number; 5} 6 7function findUser(userId: User['id']) { ... }; 8function getUserProfilePhoto(userId: User['id']) { ... };
Here, If I ever decided to change the user ID type to a number, all userId
instances would be automatically updated.
Not only that, but if there were any instances where the ID is specifically treated as a string
(e.g. userId.toUppercase()
), I would get a compile time error.
This would force me to decide how to handle this situation, and it would avoid any future runtime errors.