Unions and Narrowing 28 exercises

Correctly Narrowing a Map in TypeScript

The issue with our code is that TypeScript doesn't understand the relationship between .has and .get on a Map like it does with a regular object.

In a Map, the .has() function just returns a boolean. TypeScript doesn't know that the boolean is related to the Map in any way, so when it trie

Loading solution


00:00 Okay, the reason this doesn't work is because TypeScript doesn't understand the relationship between .has and .get here. It doesn't keep track on the map here, what types are available on it, or what keys are available on it, or what keys aren't.

00:16 If we were handling it like a normal object here, it actually would, and it would do a really good job. But we don't want to change the map, we don't want to do anything like that, so how can we refactor this code slightly to make it work better? To just hone that point more, this .has function here, it just returns a boolean.

00:35 TypeScript doesn't know that that boolean is related to that map in any way, and so when it tries to do the .get here, it's just returning event or undefined. So the way that I would solve this is I would first of all just extract this to a constant, and so I would just call this event.

00:55 And now I can move this outside of the if statement here, and now instead of using the .has function, I can just check if event exists. And now, if the event exists, we can see that TypeScript is able to disambiguate between the event or undefined.

01:13 And so inside this if statement here, and inside this scope, it's typed as event. So this is the way that I would do it, just to work a bit more closely to what TypeScript sort of wants to do in sort of figuring out the relationship between variables,

01:29 instead of relying on just methods like .has and .get. Not that you can't use those, but they just get a little bit annoying with TypeScript sometimes, and it's worth knowing this gotcha.