Unions and Narrowing 28 exercises

Returning `never` to Narrow Types

The reason why the throwError function doesn't work as expected is because of the undefined return type annotation:

const throwError = (message: string): undefined => {
throw new Error(message);

In reality, we are not actually returning undefined from this function.


Loading solution


00:00 Okay, so the reason that this whole setup doesn't really work is because of this undefined type annotation here Which is on the return type of the throw error function if we think about it We're not actually returning undefined from this function if we were to return

00:15 Undefined like this then this function would make more sense the throw new error would never be hit and you can see that because it's Slightly grayed out and I think it's you can hover over it and see unreachable code detected And now the ID would actually be a result of the throw error function, which doesn't throw an error anymore It just returns undefined

00:33 So the ID now string are undefined that makes sense and you notice though We can actually delete that completely and maybe add never on instead because never is actually the thing that this function is Returning right? It's never ever returning

00:49 So now what happens when never is included in like let's say you have a type example equals string or never we can see that example is only string because never in that situation kind of like is Assignable to string and so it sort of melds itself out of the Union

01:10 It removes itself from the Union so you end up with just string there So we have string params ID could result in a string or it could result in never Meaning the ID is typed a string and this pattern is super duper useful because it means that TypeScript can like Throwing an error in like in situ right here

01:30 Like in the space where a value might be can actually mean that you get really nice or to complete and this is a nice Pattern I recommend you take note of it But you notice to the return type on our throw error function. This can actually lie to us pretty badly we can have like a String inside here like an object and I'll throw error function won't actually

01:50 Like error and that's because never is assignable to anything That's why it works and when it you kind of combine it with a string it removes itself from the Union because it's Assignable to string and so this return type can lie quite badly to us

02:07 You'll notice though in the second solution that we can actually just omit it completely and when we do omit it Then throw error just returns never and that's what TypeScript infers here And that is really really nice because it means that first of all We've got one less annotation to worry about

02:26 second of all if we ever kind of make a change to this then that will ripple out and the rest of our codebase and Thirdly it just gets it correct. So this is I think an interesting argument for maybe not using implicit return types in your code