Check out a free preview of the full Intermediate TypeScript, v2 course

The "Utility Types" Lesson is part of the full, Intermediate TypeScript, v2 course featured in this preview video. Here's what you'd learn in this lesson:

Mike introduces the concept of utility types including the "extract" and "exclude" utility types. The "extract" utility type allows you to obtain a subpart of a type that matches another type, while the "exclude" utility type allows you to obtain a subpart of a type that does not match another type.


Transcript from the "Utility Types" Lesson

>> So at the beginning of the course, I promised that we would think about utility types that come with TypeScript. You can think of this almost like a standard library that ships with TypeScript. And we're gonna start digging into them now because we finally have all of the elements we need to tackle a few of them, right?

Conditional types are a big part of some of these built-in utility types. So first, we're going to look at extract. The purpose of extract is you want to obtain some subpart of a type that matches another type. So I'll show you an example, so we've got FavoriteColors, it's a medium cardinality union type here, there are a lot of things that it could be.

A lot of string literals, we've got a tuple here with three numbers, we've got an object that represents red, green, blue, it has properties red, green, blue. And what we can do is say, I want to extract the subset of FavoriteColors, which is assignable to type string. What do we get out?

Only the strings. If we wanna get the types that are assignable to objects, we only get the one object. Sorry, we're comparing to this type. So it's just like, give me those parts of FavoriteColors that are type equivalent to an object with a red property which is a number.

And there we go, we get that. And then the tuples, we could do that, too. We could get number, number, number out of this, we could also do this. Is that gonna work? Nope, I have to do, Is that gonna work? Yep, anything that's array-ish, get me the subpart of FavoriteColors that is array-ish.

>> We're doing an implicit satisfies inside.
>> Well, let's pop the hood, let's see what it looks like. There's your conditional type. So let's see if we can understand this, I wanna go through the next type cuz it's kind of the opposite. And we can look at how these two types work simultaneously cuz they're sort of one is the anti of the other.

It's not just hand me the piece of tea that is type equivalent to you, we're saying, hand me the piece of tea except for the stuff that is type equivalent to you. So you're saying exclude anything that is you-ish. So let's look at our NonStringColors example here, and we would get the tuple and the object.

We're saying get rid of anything that is assignable to string, give me the rest. Exclude those things that are assignable to string. So here's how they work behind the scenes, I've added an underscore so I don't collide with the real definition here that TypeScript provides cuz you can't redeclare type aliases.

So let's break this down, and let's keep this in mind here. So if we said, I'm gonna bring the other example lower so we can have it all in the same viewport here. Let's look at extract first since we cover that first. So what we're saying here is T extends U, so as long as T extends U evaluate out to T, otherwise, evaluate out to never.

And here's something important to observe about the way never behaves in a union type, it disappears.
>> It's like it was never there.
>> It's like it was never there, right?
>> [LAUGH]
>> Remember when I showed this union type, remember we said back up here, This example, remember we had 10 or 2, and I said that, I'll leave these both up.

I told you to think about this as equivalent. These mean the same thing, Boolean, Boolean. So when we see this, this top example, 10 or 2, it's as if we're evaluating piece by piece and unioning them all together. And so if we go down here and we think about this extract, we're gonna one by one take those things that are in FavoriteColors.

And if they match U in this case, it would be like, is the dark sienna, is that a subtype of string? Sure, it is. Okay, that's T, that's dark sienna. We'll call this a RunningType. And we're gonna do a couple other strings. And then there will be a bunch of things that don't match this condition, and those we'll value out to never.

And the never just melt away, that's how extract works, that's why it's convenient to use never here. We're taking advantage of the way that the union sort of fans out, and then the things that match our condition, they turn in, they sort of pass straight through. And then the things that don't, they turn into nevers.

We union that together and the nevers melt away, and we're left with only the things that match. Exclude, if we bring this down, we'll bring it up so you can see it above. Wow, it looks like very, very similar, except the conditions flipped. Those things that match string, They will turn into nevers, everything that doesn't match passes straight through.

We union all of the results together, the things that match to string meltaway because they turned into nevers. And we're left with only the things that did not match the condition, that's exclude. Does that make sense? Thinking about never in the abstract, it's a little mind-blowing, it's sort of very strange concept, but you can see that the way never behaves in this situation is quite useful, right?

We can sort of transform things, and if it becomes a never, it melts away when we do a union. Mahmood has a question, what happens if we're trying to extract things that no value satisfy? This is why I love doing this in VS code, where I can just, let's try it.

Can I do that? I'm just trying to get too clever here, Symbol. Well, we're excluding nothing. What do you think happens on the other side? We're extracting nothing, so what does that mean we're gonna get? [INAUDIBLE]
>> I hope so. Thank God. Sometimes these things turn into any, and you're like, no, [LAUGH] it broke.

This doesn't work but yeah, we're extracting nothing, or we're excluding nothing. So we get the whole thing if we extract nothing. Sorry, we get the whole thing if we exclude nothing, and when we extract and nothing matches the thing that describes what we're trying to extract, we're left with an empty bag.

Nothing matched, I have nothing to give you, never.
>> Is there a difference between using extract and using the ampersand to narrow down types?
>> It's a very good question. I would have to look at how a union type would work there. Let's try that. So, = like this, you could try that.

FavoriteColors, string. What do we get? I mean, I know this one's gonna work. The tooltip is just not very helpful here. Go ahead.
>> Try assigning a new variable to type it as type example.
>> And see what we can put in it?
>> Yeah, declare a variable x as example.

>> Is it x is unused? No, so it's happy with that. It's unhappy with that. Yeah, let's give it a string that's not in the type. Yep, I'm seeing similar behavior here. Having not had much of a chance to dig into this, I wouldn't make the claim that this always works, but it's certainly working for this example.

You couldn't exclude, With that intersection type. You couldn't say, give me things other than the intersection of these two types. I think you could model extract that way, but I don't think you could model exclude.

Learn Straight from the Experts Who Shape the Modern Web

  • In-depth Courses
  • Industry Leading Experts
  • Learning Paths
  • Live Interactive Workshops
Get Unlimited Access Now