Unions and Narrowing 29 exercises
solution

Handle Error and Success States by Narrowing

Currently our ApiResponse is too wide:


type ApiResponse = [string, User[] | string];

We need to split it into two separate states: the error state and the success state.

Let's start by handling the error state of our API response.

Handling the Error State

In this scenari

Loading solution

Transcript

00:00 Okay, so API response. Now we need to split these out into two separate states two separate possibilities because currently it's too like wide It's not helpful enough. So let's do the error state first. Let's imagine that instead of string We now want to say okay One of the possibilities here is you return an error and then the string that comes with it, which is the message

00:20 Okay, nice, but now we're getting an error here saying success is not assignable to type error Well, we can add a member to this discriminated union And this is a discriminated union where we have success in the first one and then an array of users in the second The discriminator is the first member of the tuple

00:38 so we have either the first one being error or the First one being success and the first member of the tuple then defines the second member of the tuple So error string success user and now everything inside the function works really nicely

00:52 So we're getting like we have proper results here. So if I try to return an array of users inside of here It's going to error because first of all it says, oh my god, it's saying a bunch of different horrible stuff Oh, yeah, of course because I'm actually trying to write some TypeScript in a JavaScript slots. That wasn't good. So we have type

01:11 Empty object is not assignable to either of the possibilities here So imagine if it was just an empty array Then we would get an error here saying type of position 1 in source is not compatible with type position 1 in target So basically type this array is not assignable to type string string is the only thing we can pass in this slot

01:31 But how about down the bottom because down the bottom? You notice that before we talked about destructuring in discriminated unions and how you can't do it here. We're Destructuring we're using an array destructure pulling out the status and the value and you might think in these situations Well status and value. They're Totally unrelated to each other. They're pulled into two separate variables

01:52 But TypeScript actually with tuples and with discriminated tuples, it keeps track of that relationship So if you check that status is success then value is actually narrowed down by relationship What how cool is that? This works for discriminated tuples not discriminated objects

02:13 I don't actually know the reasoning for that This is how it works and then on the else branch here then value is going to be string and everywhere else It's either string or user so cool. So clever and it's actually a really nice use case for discriminated tuples it's cool that TypeScript lets you do this lets you return kind of like a double from your

02:33 Function in this way lets you pull them out into different variables and lets you kind of you like narrow them based on the value Of the other very nice