Objects 16 exercises

Manage Subtypes with the Pick Utility Type

Let's start by looking at the first solution using interface extends.

Use interface extends with User

To use interface extends, we'll first create a new NameAndEmail interface, which contains the name and email properties. Then we'll have the User interface extend it:

Loading solution


00:00 Okay, let's take a look at the first solution. The first solution is basically to use interface extends with our user. So now we have an interface of name and email containing name and email and our interface user extends name and email. So we're kind of pulling out the bits that we actually want to go in our fetch user

00:18 and our fetch user returns a promise of name and email here. Okay, seems fine. And we get kind of some nice benefits of this. You know, we're using interface extends here but it can feel a little bit annoying like I just want to see all the properties of user in one place but now I need to check name and email, check if that extends anything.

00:36 And so this can lead to a little bit of misdirection here but there's another interesting way to do it. Instead of just having kind of like promise user inside here or promise name and email, we can use the pick utility type and we can inside this function kind of declare what types of user

00:53 or what members, what properties of user we want to grab. So we have pick here and we say as the first argument to pick and let me just pull this out so you can see more clearly type picked user, can't spell, is we're saying pick user and let me just put that inside the promise,

01:12 pick user name and you notice we get autocomplete here too or email. And now by passing a union into this picked user, you can see, we can hover over, we can see we're getting name email here. And now if I change this to, let's say, I don't know, maybe I change email

01:30 to let's say a special email type or something, I don't know, domain string or something, then this picked user is going to correspond to that. So it's kind of like we have a single source of truth for our type inside our user interface but then if we want to break it down into smaller pieces,

01:48 we can just pick the ones that we want. And of course, we can just pick all the types if we want, we can say ID or role here too. So there's no limit onto how many types we can pick out of this. And we can also just choose one if we want. So just if we want just an object with user name, then this works great. Now, bear in mind that pick works for objects,

02:07 pick and some other type helper that we'll see in a minute. It doesn't work for unions, right? So if I were to say pick A or B and then like just grab A out of this, then that doesn't make sense because then you end up with, you're picking parts of an object out of this and the only things that are available on these two things

02:26 are like the things that are available on string methods. So this pick only works on objects, that's really worth remembering. And it means that you can kind of like declare little subtypes of your interfaces without having to mess up the structure

02:43 of the original interface too much and obscure it. I think this is a really, really powerful thing to do. And it means that you can have single sources of truth for your types while also adding subtypes throughout your code base.