I assume you know about types in TypeScript. That is kinda the essence.
And you've probably run into situations where you want to or together different things into a type. Like me, when I want to summarize beers I like, I can say:
type AtlesKindOfBeer = 'ipa' | 'stout' | 'lambic';
Whith this defined, I can create a function like this:
const serveAtleBeer = (beer: AtlesKindOfBeer) => console.log("Cheers");
This means that we avoid situations like this:
serveAtleBeer('lite banana-neipa');
But, say that you are handed a string describing a beer style, and want to check if this is a beer I like?
Typeguards to the rescue!
const isAtlesKindOfBeer = (beer: string): beer is AtlesKindOfBeer
=> ['ipa', 'stout', 'lambic'].inludes(beer);
This works. Kinda. See the problem? Duplication! Say that I want to add "geuze" to my list of drinkable beers. Then I have to update both the AtlesKindOfBeer
type and the isAtlesKindOfBeer
typeguard. And here lies a potential for fuckup. And every potential for fuckup will, someday, develop into a fuckup.
So, how do we eliminate the potential? We define the list of beers I like once. Like this:
const atlesKindsOfBeer = ['ipa', 'stout', 'lambic'] as const;
then both the type and the typeguard can reference this list:
type AtlesKindOfBeer = typeof atlesKindsOfBeer[number];
const isAtlesKindOfBeer = (beer: string): beer is AtlesKindOfBeer
=> atlesKindsOfBeer.inludes(beer as AtlesKindOfBeer);
Hooray!
Btw: the as const
syntax is known as a [const assertion]!(https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-4.html#const-assertions)
Top comments (0)