Use a Type Predicate to Filter Types
There are multiple solutions here.
The Hacky Solution
The first solution is a little bit hacky, and looks like this:
0:00 There are multiple solutions here. The first solution is a little bit hacky. What we're doing is we're basically saying, "The values that we get back from this filter we're saying as an array of strings." This is pretty acceptable. It's fine.
0:14 We're saying, "In this case, we do know more than TypeScript. We know that it's impossible to have undefined in this array. It's fine to say as an array of strings here." It's not the prettiest solution. A really pretty solution is to turn the function that we pass to this filter into a type predicate.
0:35 A type predicate basically expresses a return type by saying something is something. This value is value is string. What it's doing here is we're passing a function into values.filter, which is returning a boolean. It has to return a boolean, by the way.
0:54 If we just change this to, let's say, "If value return array," then this is going to yell at us because a type predicate has to be a boolean, even if we extract this out. Even if we say, "Const predicates equals this." Then value is going to be string or undefined.
1:17 Then if we return array, then this is going to yell at us because it's not assignable type boolean. This marks it as a type predicate. Type predicates have to return booleans. We'll pass that in, predicates. Then we can return boolean value. What that's doing is it's filtering out, it's saying, "For each value in this array, we're going to mark it as a string."
1:43 I can say value is number here. This is interesting because a type predicates type must be assignable to its parameters type. It's not letting me stretch the bounds of this too much in a similar way to as, actually. If I remove this, and then say, "As string arrays we had before," I can't do as number array here because string is not comparable to type number.
2:08 String or undefined is not comparable to type number. Weirdly, with a type predicate, I still can lie here. I still can say value is undefined. Now what I end up with is an array of undefined things, even though this is checking for the opposite. Type predicates are super useful. We're going to see in this section how useful they are.
2:30 Bear in mind, they are about as safe as an as. They are about as safe. Sure, I can't do anything crazy. I can't say value is number. I can't say value is a random object with stuff in. I can make it so that this return type lies, which is a bit of an issue. You're going to see how useful type predicates still are.