Check out a free preview of the full Intermediate TypeScript, v2 course:
The "Filtering Properties" 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 discusses the concept of filtering properties and demonstrates two different approaches: one where the keys are filtered first and then mapped, and another where the keys are iterated over and filtered using a conditional type. The advantages of filtering the keys first and a syntax for filtering keys using a filtering expression before the right square bracket and casting are also discussed in this segment.

Get Unlimited Access Now

Transcript from the "Filtering Properties" Lesson

[00:00:00]
>> All right, let's talk a little bit about filtering properties out. And this is actually the last section of this unit. So, we'll go back to filtering things out of an existing type. So in this case, it's the document object, as in, window.document. So we can get keys here.

[00:00:24] Keys that begin with query. It's query anything, that's what this means. Query followed by string. So we're gonna extract the keys of the document type which match this pattern. Again Ls in chat you're asking about regex's. Little regex, right? You can you can specify a prefix and then a wildcard can do everything, in first kind of like capture groups, right?

[00:00:53] I mean, you can serve, maybe this is a regex, who knows? So, let's look at what we've got here. We've got keyFilteredDuck. Interesting, everything starts with query. That's pretty great. So, this is kind of what we would hope to get. Here's an example of what not to do.

[00:01:15] And we're gonna compare it to what worked out pretty well for us just now. So, it's a different approach here, where we are not filtering the keys first. Here what we're doing is we're saying, iterate over all keys present in keyof Document. And then as the value type here, we have a conditional type.

[00:01:44] So we're saying, all right, for each key in Document, if Document extends and then what is this here? It is a function that accepts any arguments and returns either an element or an array of elements. We don't care what the arguments are. But the filter here is only those functions that return an element or an array of elements.

[00:02:08] I tried to keep it in spirit with things that begin with the word query on Document cuz that's querying the DOM, right? These are like, give me all the things to get like one element or many elements. And then if that condition is met, here we are using Document[K], right?

[00:02:25] That's kind of like this thing up here. It effectively means, let that thing pass through. Give me the value type that was there, otherwise, give me never. Let's look at how that turned out. Look at that junk, look at all those nevers. There are 249 more things here, and yes, query selector is gonna be there and it's gonna have the correct type.

[00:02:56] But we didn't filter the keys, what you wanna do is filter the keys in advance, as we're doing up here, right? We extracted the keys that met a particular condition, and then put them through the map type. This is similar to array.map, right? You're gonna get something out of the array.map.

[00:03:23] It's the same length of the array that you put in. That's how mapping works. If you want it to filter and then map, you do them in that order. But if you want as your mapping, to try to filter things out, it's almost like the best you could do is set things equal to null.

[00:03:41] You're gonna end up with a bunch of nulls in the array and then, okay, now we've gotta go filter all those nulls out, it's kind of a pain. So these are two ways of doing this, but clearly, first of all, this is less code. This is much easier to debug.

[00:03:58] But this is a mistake people make sometimes where you gotta remember a map type, it's you're gonna get generally the same keys you put in. You're going to get those as properties out. You're gonna get one for each. And the fact that we haven't filtered here means well it has the same number of properties as the full document object, but most of it's just not useful and not usable.

[00:04:27] This will slow down your TypeScript compilation because it's gotta think about all these fields that are there, and they're read-only, and they're of type never, and type checking against this is gonna be a pain. So that's my advice there, and here's filtering the keys first. I think we already had this up top.

[00:04:53] I think this is just an abbreviated, sorry, this is an abbreviated version of the general case. So up here we're using Document, right? Document's hard-coded into our type and down here, this we're just calling it we're calling it T is that type and U is the set of keys.

[00:05:17] And this is an example of the ability to filter keys. So for each key in T, if the value type extends something you're interested in, return the property name, otherwise evaluate to never.
>> It was some time ago they introduced a new way of operating on the how you're iterating over the key of or the keys of T.

[00:05:48] Where you can put a filtering expression before the right square bracket and cast something, using the as keyword, you can use T and P to determine whether to return the key or never, and that sort of prefilters.
>> Really.
>> You're projecting into.
>> I honestly have never seen that.

[00:06:14] Can you help us get to that syntax here?
>> Sure.
>> So the value filtered doc the bad way.
>> Yeah let's start here
>> And refactor that.
>> Let's do it.
>> If you take the Documents [K] extends blah blah blah.
>> Over here.
>> Never
>> Yep.

[00:06:33]
>> So take take that whole block and cut it. Then we're gonna wanna paste inside that square bracket, just after keyof Document, yep.
>> This whole thing.
>> Yep.
>> Wow.
>> So as paste. And then as.
>> And the ternary we should take out.
>> Instead of returning Documents[K], just return K on 152.

[00:07:05]
>> So but we really want a conditional here or do we want. Sorry, I don't understand
>> So on 150, it'll probably make sense as soon as we finish and clean up the syntax.
>> Okay.
>> It's a little busted.
>> Let's do it Document[K].
>> Yep and then on 152, Documents[K] should just be K.

[00:07:28] Cuz what we wanna do is prefilter all the keys.
>> Holy cow.
>> Yeah.
>> I learned something today.
>> So now if you hover over that on 148 you'll only get your ten or so.
>> There they are, adoptNode is there. Yep, wow that is valid. I somehow missed this.

[00:07:53] That's really cool, we're filtering the keys, I'm gonna delete this. Oops, not the whole thing, just the do not use it
>> I would still generally recommend as as you have been use the utility types because their way better maintained and well understood they're idiomatic.
>> Yep.
>> This is if your hand rolling some super stupid custom stuff this is nice to know but [LAUGH].

[00:08:19]
>> That's super cool thank you for pointing that out.