Intermediate TypeScript Extract & Exclude
Transcript from the "Extract & Exclude" Lesson
>> Extract and exclude, these utility types which are included as part of TypeScript, they're used to obtain some sub part of a type, either through specifying what you're looking for, or what you're not looking for. Extract is about defining what you're looking for and you get that piece.
[00:00:24] Exclude is about describing what you want to leave behind, and you kind of get everything else. So these, behind the scenes, just use a conditional type. So we'll be able to put this concept we just learned into action now. So let's say we have a type that looks like this.
[00:00:44] So we have favorite colors, and we have a bunch of colors that are listed, right? So think of this, if we were in CSS and we were using the color or background color property, you can write out the word red. Or you can define colors like hash, F00.
[00:01:05] Or you could say RGB parentheses 255. You could specify your decimal values for each of those eight bit color slots. So we're allowing all of that here. So we kind of have a mix, right? We have strings, we have a three part tuple. And then we have an object with properties red, green and blue.
[00:01:28] So if we wanted to obtain only the subset of what's described by this type, that is also a string, we could use extract in this way. If we scroll to the right, you can see that we get just the strings. The tuple is not there, the object is not there.
[00:01:52] We could do the same thing by changing this second thing, the second type that we pass to extract. And now what we're saying is within favorite colors, give me whatever sub part of this type has a property called red, whose type is a number. We don't need to specify this whole thing here.
[00:02:21] Remember, it's not an exact match. This is a minimum requirement. So let's pop this example out into the playground, and let's say, what if we did this? Let's add an alpha channel, right? We could, well, this is not gonna be because it overlaps so much with the other type.
[00:02:44] Let's say I'm just gonna do this. I just don't want one to be strictly a superset of the other. I want them to have some overlap where we can see an interesting thing. So if we look at object colors, now look, we selected both of those, if you see in the tooltip.
[00:03:02] The object that has green and blue written as words versus their first letter. So it's almost like a query searching for things that might contain a substring of, here's a fragment, you'll find me the whole thing. You can think of it kind of that way, at least when we're using it in this context.
[00:03:21] This is where we're doing the searching. Make that a little bigger. This is where we're doing the searching. And then this is the clue, right? This is the fragment to use as the basis for the search. That would be a perfectly valid way to think about this. And of course, with tuple colors, I'm just gonna pop back here.
[00:03:44] We could search so the result we get, of course is number, number, number. Let's try some other things here. What if we just search for things like a tuple of length 1, we get a never, not found, right? That's what it is in this case. It's like I examined everything, and here's the set I found, developer, it's an empty set, sorry.
[00:04:09] But if we did this, what if it's a wider type, a more general type that still kind of matches what we're looking for. Hey, there we go. Yeah, an array of numbers that is exactly three slots. Sure, I mean, it is an array of numbers. It's a very special array of numbers, it's specific, but we can search for something that is more general.
[00:04:38] In the same way that up here, right, we're searching for any object that has a property red whose value is a number. And we were picking up more than one thing. So you search with something that's more general and the matches will be at that level of specificity, or even more specific, right?
[00:04:59] We're searching for any number arrays. And if we had, let's say we allowed an alpha channel here, maybe this one might work in a more interesting way. So now we'll get both. We'll get the three place tuple and the four place tuple. Why? They're both different kinds of number arrays.
[00:05:17] So one of the key insights I wanna make sure you walk away with, how to think of this specific versus general. What's this extends keyword all about? And this is really important in terms of making sense of what we're looking at here. Yeah, so in plain language, what this type is all about, we're extracting the subset of favorite colors that is assignable to string.
[00:05:43] That's specifically this thing up here, right, where we're grabbing the subset that is assignable to a type Exclude is the opposite of extract. And it's useful if you can very easily define what you wish to leave behind. So it's the same exact example, I've just changed the word extract to exclude, and here we're saying, show me all.
[00:06:16] Show me everything that doesn't match string. Show me everything that doesn't match string. So we get our array of numbers and we get our object. Those are the non string parts of favorite colors. So, how does it work? Here are the definitions of these two types. This is pulled straight out of the TypeScript source code, and it's very, very similar to what we were working with before.
[00:06:47] So in plain language, here's what's happening. We have a type T, this is a type parameter, and it's what we're operating on. In this case up here, we used favorite colors, right? It's this mixed bag. It's the haystack in which we're searching for a needle. And then we have typed U, U describes what we're searching for.
[00:07:12] So you can think of this almost like we look at all the different parts of type T, especially if it is a union type with this whole operator here. We're gonna look at each piece of it and we're going to see which of those pieces extend from you.
[00:07:34] Which of them match U or are even more specific than U but still match the minimum requirement of U? If this turns out to be true in the exclude case, we leave it out. We leave out whatever matches, otherwise we let it pass through. And this is the only difference between the two.
[00:07:58] It's never colon T versus T colon never. It's just the inverse condition, right? So this is a good example of how you might use conditional types.