Simplifying TypeScript with Type Predicates
We need to find a type for the isInvalid
function.
It would be nice if we could do something like saying isInvalid
takes whatever
and whatever is boolean
:
isInvalid(whatever: any): whatever is boolean { ... }
Unfortunately no parameters are being passed in so a solution like
Transcript
0:00 The solution here is we have this is invalid function. We need to find a type for this. The syntax I was referring to is this whatever is Boolean, for instance. Imagine if we had whatever inside here, which might be any, for instance. Then we assert that whatever is a Boolean.
0:21 We don't have access to anything here because we're not passing anything into the arguments here. There's no parameters on this function. What we can do instead is we can actually say, "This is..." and, for instance, let's say, "...form. Then T values. " Why don't we add error string?
0:45 Now what happens is we're saying this, the thing that the this is being called on, this form right here, is a form and an error string here, which overrides the initial error. You end up with form.error is always going to be a string. This means that you get this really nice bit of logic where you can call type predicates to assert that the value of the class is a certain shape. Super nice.
1:18 There's even a funkier way of expressing this, which is you can say, "This is form T values." This actually, it's always going to be form T values. You can actually do, "This is this and error string." What? This is this. This refers to this. Then this refers to the type of this, which, in this case, is going to be form T values.
1:43 You can actually use this inside a subclass of another class. This will always refer to the right thing. It's incredibly cool. Again, we're getting all the right inference here. This is a very simple version of this. We're going to look at a couple more, one more with assertion functions as well. You can imagine that this is actually fairly powerful.
2:01 It gets you quite far without needing to do much crazy generics work. We've got this is this and error string. The issue is, though, that, of course, like all type predicates, it is reliant on you defining it properly. If we accidentally define it, it's not actually going to error here. TypeScript thinks that this is safe.
2:24 This actually ends up being form.error. If we look at it, actually ends up being undefined when we know it's actually a string. You got to be careful. Type predicates are about as safe as as but very, very useful.