Specifying Types for an Overloaded Function
The solution to this exercise relies on remembering that the implementation signature does not get exposed outside of the function.
// This is the implementation signature that is not exposed
function getRolePrivileges(role: string): AnonymousPrivileges {
...
When using functio
Transcript
0:00 The solution to this exercise relies on knowing that this implementation signature does not get exposed outside of the function. We covered this in a previous solution, but this exercise really drives it home. It brings into focus the idea that this one here is just an amalgamation of all of the function overloads that come before it.
0:22 What we've got here is getRolePrivileges("anonymous") is erroring. This should give you a clue. This is telling us that we can't pass this. In fact, the only things we can pass are admin and user. We know that we're going to need to make this into a new function overload up here.
0:42 Let's take a look now. This appears to be working. We do get overloads here for admin and user, which is really nice. We can pass in other things, too, which is super cool just by itself. That's something that you can take from function overloads, is that you can use them to get autocomplete on string literals that can accept other things. There are other techniques for that, but it's pretty cool.
1:08 Now we've got some issues inside our function here. What do we do inside here? How do we type this? The implementation signature has to be something that amalgamates all of the others here. One thing we could do is we could have role, any and return any. This is dirty. We shouldn't be allowed to do this.
1:32 One thing we can do is we can call role string here, admin, user, or string, which is interesting. If I leave off string, of course, then this is not compatible, because you can't pass strings to something that could accept admin or user. Admin, user, or string is the same as string. TypeScript is not going to give us anything else there.
1:55 Admin and user get collapsed into string, so it might as well just be string. Now what do we put for this any here? AdminPrivileges and AnonymousPrivileges, they're all related. They all extend from AnonymousPrivileges here, and then admin extends from user.
2:15 The safest thing to do is to do AnonymousPrivileges, UserPrivileges, or AdminPrivileges here, making this return type an amalgam of these three things. Of course, we could delete this as well, but then we start getting some issues here because getRolePrivileges here, AdminPrivileges, it's saying that it's not compatible when we do know that it is.
2:40 This is the safest thing to do, is to make your implementation signature return a union of all of the possible things that are in there. It's possible to get smarter than that, but this is about as smart as you want to be. You don't want to get too clever here.
2:55 Now everything's working. We've got our AnonymousPrivileges coming through, got our UserPrivileges, got our AdminPrivileges. I want to test. It is possible to return the wrong things from this, too. You can return sitesCanDelete.
3:07 It's pretty hard to be super type-safe with a implementation function of a function overload. You have to try and do the best that you can and make sure that at least the user that's using your function is getting what they expect. Similar to generic functions, there are limitations with how type-safe you can be inside the generic function or function overload that you're creating here.
3:38 Again, pros and cons, but this looks pretty nice. It gives you some really nice autocomplete as the person using this. It's a pretty easy thing to look at for someone stumbling on this.