Unions and Narrowing 28 exercises

Dynamically Handling Different API Responses in TypeScript

It may be tempting to change the APIReponse type to make it a little bit different. For example, we could add an error as a string on one side and data as undefined on the other branch:

// Don't change the type like this!
type APIResponse =
| {
data: {
id: string;

Loading solution


00:00 Okay, the solution is this you might think maybe we can change the type to make it a little bit different here Maybe we can add like error is a string on side here that might fix this branch and then we could do Like data is undefined or something on this branch No

00:16 there's a much simpler way of doing this and the way that you can do it is by inside this if condition saying if data in response Boom, what this does is it checks if there is a data key on the response here?

00:34 And what this means then is if this resolves to true It means that we must be in the branch where data is on here If we had like a version of this where you could pass in data on this one, then it wouldn't actually like disambiguate anything It wouldn't tell us anything because like data is available on both of the branches

00:53 But because data is not available on one of the branches then it means that we get to narrow it properly here This also makes our tests pass too And it means that if we were throwing an error down the bottom here Then it's sort of well actually because of the return statement it does Manage to narrow this but if we were operating outside of an environment where we were narrowing

01:13 We would still just get this API response. We still have both branches available, but inside this else it Understands that if it's not the one with data on then it must be the one with error on and so the response inside the Throw new error is actually just narrowing to exactly what we want it to be too

01:33 So this is a really really useful piece of syntax for narrowing down objects that might have different keys from each other