Unions and Narrowing 29 exercises
solution

Simplified Type Guards with TypeScript 5.5

TypeScript 5.5 has introduced a remarkably simple solution to this problem that used to be much more complicated.

Create an isArrayOfStrings function that takes the original logic from the joinNames and createSections functions that returns a boolean indicating whether the value is an array

Loading solution

Transcript

00:00 The solution here is amazingly simple. This used to be a much more complicated problem to solve, but since TypeScript 5.5, which as of the time of recording has just been released, we can now do this. I can just copy this logic into here. I can say const isArrayOfStrings, and then I'll just

00:19 return this value here. Obviously, we're getting some errors because value is not defined. So let's define it here saying value is a type unknown. And now I can just replace the logic inside here and just say isArrayOfStrings calling it on value.

00:35 And it works. Now, this is amazing to me. I mean, to you watching this in the future, this might not be so amazing because TypeScript will have had this for a while. But what's happening here is if we hover over isArrayOfStrings here, then you can see that we have the function parameter just there.

00:52 In fact, I'll zoom in a touch. And we have a return type here, which looks very interesting. We have valueUnknown as the parameter, and the return type is valueIsStringArray. This is what's called a type predicate. And type predicates are something which are quite advanced in TypeScript. We will look at them, I think, probably in maybe the

01:12 last chapter of this. And what's going on here is that TypeScript is inferring the fact that we're returning this logic inside here. We're doing some narrowing inside there. And it's inferring the fact that this function, when it returns true, will mean that value is inferred as an array of

01:30 strings. So when we call it on here like this, it means that value is an array of strings. If we were to do the reverse, if we say it's not an array of strings, then value inside here would still be unknown. But outside of those brackets, value would be an array of strings. So it's like we're

01:48 able to recapture some of this narrowing logic, put it inside a function, and it just works. You are, of course, allowed to add your own to here. And actually, 1 thing you'll notice is if you add a return type here, if you add Boolean as the return type, then everything actually stops working. If we hover over this, we can see value unknown

02:08 returns a Boolean. And because it's not returning any special awareness of what value is supposed to be here, it means that value is still unknown here. So this is a good argument for actually not annotating your return types because if you're adding this interesting narrowing logic here, then your function is going to be automatically

02:28 inferred as a type guard. Really, really clever stuff.