TS Tricks: Type Guards
With everyone getting excited about Typescript I thought it'd be fun to do a walkthrough of one of my favorite features, type guards. These are type-safe functions that allow us to assert that an argument matches a certain type. The best part is these work at runtime!
With everyone getting excited about Typescript I thought it'd be fun to do a walkthrough of one of my favorite features, type guards. These are type-safe functions that allow us to assert that an argument matches a certain type. The best part is these work at runtime!
Let's start with a basic example below:
We've declared some interfaces here: Person
, Wizard
, and Muggle
. Wizard
and Muggle
are both instances of Person
, however they have an extra property. Pretty standard so far.
But now let's create a type guard!
We now have functions called isWizard
and isMuggle
. These functions return a boolean at runtime, but in Typescript land they return person is Wizard
or person is Muggle
. At compile time we'll get static type checking on our instances.
These functions are all 100% type-safe. In fact, if we were to try to get spells off a Muggle
we would get a type error.
These functions always return the right thing because we have validation at both runtime and compile time. It's basically a free unit test!
Note: It's one free unit test per function, you should write others.
Let's make this more complicated now, let's extend Wizard
.
Now each Wizard
has a house
property for a Hogwarts house. Just like before we could make new interfaces for each house.
And once again, we can make simple type guards for each house. But this time we'll also reuse our isWizard
guard. After all, only wizards can go to Hogwarts!
Let's have some fun now, let's throw together a makeshift datastore and do some functional programming. If you're new to FP you can check out my previous article here.
Now we have an array of people. These people may or may not be Wizards and their Hogwarts houses vary.
We can now make functions that filter
over the list of people and return the ones that match a type.
We can also combine these with a map
to get data we care about.
If these look like redux selectors, it's because this pattern is very commonly used to get data out of a typed redux store. If you want to know more about that, I wrote an article about building a typed and code-split redux store.