Conditional Types and Infer 10 exercises

Prevent Unwanted Type Scenarios from Happening

There's a lot going on to this solution, so let's construct it from scratch.

Here's our starting point:

type YouSayGoodbyeAndISayHello<T> = T extends "hello" ? "goodbye" : "hello";

The first thing we want to do is check if T extends "hello" or "goodbye". For now we'll say if does th

Loading solution


0:00 Oh, boy. Here we go. This, YouSayGoodbyeAndISayHello, we're now, first of all, checking this. This looks a little bit crazy. In fact, let me construct this from scratch so you understand. I'm going to, first of all, say -- this is what the problem started with -- we want to first check if T extends hello or goodbye.

0:23 If it does, then let's just say we return wow. Otherwise, we're going to return never. Now, if I say type Example = YouSayGoodbyeAndISayHello, and I pass in whatever, then this doesn't extend this, so we're getting a never here. Whereas, if I say, hello, then we should say wow. If I say goodbye, then it's going to say wow as well.

0:50 We now know what we can make pass this initial check here. It's kind of cool that we get to use a union type here. We don't need to say T extends hello, then do something, and otherwise T extends goodbye, and do something. We can say T extends hello or goodbye, and then we can enter that branch.

1:09 Inside here, we can say T extends hello, then return goodbye, otherwise return hello. We end up with the kind of monstrosity that we have here. That means now that when we pass in something weird, we're going to hit this never branch instead of the branch that contains our actual logic.

1:28 There's no limits here to how many of these you can stack. In fact, a lot of the really, really complicated libraries use these huge stacks of conditional types that are ugly as hell to look at, but drive a lot of the complex logic. This example then is never. This means if we're passing alright pal, we're going to end up with never. If we pass in 1, we're going to end up with never.

1:49 Never is a way of signaling to your types that something should never happen. We're going to break this down in a separate part of the module, and you may indeed have seen it already. This pattern though of returning never allows your conditional types to specify their else logic without having to worry too much about what it is.

2:11 Really, if we're passing something random in here, and we try to use this never somewhere, then this never is going to throw an error pretty much wherever it's used because it should never happen.