Narrow Down the Type of Variable with Type Guards in TypeScript

Rares Matei
InstructorRares Matei

Share this video with your friends

Send Tweet
Published 5 years ago
Updated 4 years ago

As you write TypeScript, the compiler will intelligently look at the flow of your logic and how it branches out and, if possible, will attempt to narrow down the type of different variables. It starts by inspecting the widest type a variable can have, and then depending on how it is used with JavaScript keywords such as instanceof / typeof / if / else / return / switch it narrows down to a more specific type.

Instructor: [00:00] To demonstrate a feature of TypeScript called type guards, I'll be using two classes. A Book with a property title, and a Television with a property screenSize. This function relaxWith accepts an item that can either be a Book, or a Television.

[00:14] If I go, if (item instanceof Book), and I try to access a property on an item, TypeScript is only going to suggest me Book properties. If I try to access a Television property, it's going to complain.

[00:28] That's because we've introduced this check here, where an item will only go in this if block -- if it's a Book. It can't have a screenSize property. If I open an else block, again, if I try to access properties on item, it's only going to suggest me Television properties.

[00:43] That's because, by excluding Books and this first if block, the only way this line of code will run is if the item is a Television. To demonstrate this in a slightly different way, I'm going to remove the else block.

[00:54] The compiler will tell me that it can't assume that the item will have a screenSize property when this line of code runs. Because even though it will get here when the item is a Television, it's also going to get here when the item is a Book, once it finishes with the if block.

[01:08] To fix this, I can just add a return statement here. What's going to happen now is if the item is a Television, it's going to completely jump over the if block, and it's going to execute this line.

[01:19] If the item is a Book, it's going to go into the if block. Once it gets to this line, the function will completely return. Then, TypeScript can be sure that when line 14 runs, the item will be a Television.

[01:30] Another great way to take advantage of this is using typeof. I'm going to slightly refactor this and check if the typeof item is an object. If I remove the properties and I hover over item in this context, we can see it's a Book.

[01:48] While if I hover over item in here, we can see it's a string. TypeScript actually noticed that out of a Book and a string, the only one that can have a typeof object is a Book. That's why it could narrow down the typeof item in this context. While, again, because of the return statement in here, the only way this line of code will run is if the item is a string.

[02:09] To recap, we've had a look at type guards, which is when TypeScript intelligently narrows down on the typeof an item based on the flow of the logic. It achieves this by looking at all the possible types an item can initially have, then using keywords such as typeof, instanceof, return, or even switch statements, to narrow down on the typeof item in different contexts.