Unions and Narrowing 28 exercises

Resolving Literal Types to Wider Types

Let's look at how literal types resolve when used inside a wider type.

Here's an example where we have a getResolvedIconSize function that takes in an iconSize parameter of either "small", "medium", "large" or string:

const getResolvedIconSize = (
iconSize: "small" | "m

Loading explainer


00:00 Let's talk a little bit about how literal types resolve with wider types. You can see here that we have a GetResolvedIconSize function, which is taking in an icon size parameter of either small, medium, large or string. This means that if you pass in small, it's going to return 16.

00:16 It will return 32 if it's medium or return 48 if it's large. Otherwise, it just returns the icon size. Now, you would think, OK, we've got our icon size here. It means that we can pass in each of these. But let's think about the assignability chart that we saw earlier.

00:34 Here, we've got small, medium, large or string at the top here. And if you think about it, string is assignable to that. So is small, medium or large. And so if you think about it, everything inside this top area here can just be represented by string. And this means then that if we take a look,

00:55 basically all of the actual literals, when they're in a union with their wider type, they get cancelled out. And TypeScript sort of forgets that they exist because it doesn't need to really keep track of them. So all of these arrows of like small here, really because they're assignable to string, then this whole thing at the top here just counts as a string.

01:15 And we can see this in action here. So GetResolvedIconSize here, even though it's got all of this sort of stuff when you hover over it, which is quite useful, it won't give you autocomplete for small, medium or large here, which is a little bit annoying if you think about it. There is a way around this, which is a famous incantation that TypeScript wizards know about. So I will teach it to you here,

01:36 which is if you wrap this in some parentheses, give it an AND sign and then give it this empty object shape. For some reason, it just starts working. So now you get small, medium or large in this particular slot. That's a fun little trick, but not one that I would introduce to, let's say, an application code base without some previous thought.

01:57 And we will look at this syntax and what it does later. But I thought I'd just throw it in here just for a little bit of wizardry sprinkled in. But the main idea here is that you shouldn't think about literals and wider types in a union together in a way where you think, OK, it's either this or this or this. Really, all of these just get subsumed into string.

02:17 And so you might as well just be typing string in these situations.