Advanced Hooks 8 exercises
solution

Improved Type Safety with Discriminated Tuples in TypeScript

The solution is to update Result to be a discriminated tuple.

Basically, we'll take all of Result's content and put it inside of 3 different tuples.

Here's what Result looked like before:

// starting point
export type Result<T> = [
	"loading" | "success" | "error",
	T | Error | unde
Loading solution

Transcript

00:00 So, you might have figured out the solution here. It's really, really neat, which is we can use a discriminated tuple for this. So, let's say we take all of this and we basically put it inside three different tuples. So, tuple 1, tuple 2 and tuple 3. For the first

00:18 tuple, we're going to give the first member loading and the second member is going to be undefined here. For the second tuple, we can have success and this is going to be with our T attached to it. And you can see, as I filled in that, then this one worked here.

00:35 The other one that's not working is error any. So, let's put error and instead of any, let's use an error instead. So, now we've got our results properly typed. We've got loading undefined, success T, error, error. And now suddenly everything's working. Why

00:51 is it working? So, there's a few things to break down here. First of all, it's really smart that TypeScript understands that when you create this tuple, you get three different parts here, error, loading and success. I can't pass in an error, obviously, into success

01:05 because this is, like, it's not assignable to T. So, I have to start off with loading undefined. And by the way, you can also specify this as a kind of like an optional member of this tuple. So, I don't even need to pass this here if I don't want to, which is pretty

01:23 beautiful, actually. Then down here, we basically, this is really, really smart. When you destructure this, TypeScript understands the relationship between these two components. It understands

01:37 that if status is a certain thing, then value is going to be a certain thing, too. So, this breaks the rule or breaks our understanding of destructuring because you think of, like, destructuring a discriminated union of objects, this wouldn't work, surely. But with tuples,

01:53 it does. This is so, so smart. And it means, actually, we just get a really clean API up here and a really clean API down here. So, I would recommend actually using this more often, and I'm surprised that more libraries don't. It's just a really, really lovely way

02:09 to kind of make your code more understandable for the people that are consuming the functions of your library. Lovely stuff.