TypeScript Narrowing
Narrowing is a TypeScript process that refines a value of multiple types into a single, specific type.
Union types represent entities that may be one of two or more different types. Because they only allow access to members known to be on all possible types, we need to narrow down a value to a more specific type before using non-shared members.
Where Narrowing Happens
TypeScript recognizes types as being narrowed when it sees branches of JavaScript control-flow logic, including:
- Conditional statements like
if/else, ternaries, and switches. - Looping statements, such as
for- andwhile-loops. - Truthiness checks for entities that don’t point to
false-like values.
If an area of code can only be reached if a value is of a particular type, TypeScript will infer the value to be of that type in that control flow branch.
Example: Narrowing with if Statement
In this example, our logValueIfExists() function accepts a value parameter with a union-type of string | undefined. If we want TypeScript to explicitly narrow our value down to a string type, we can use an if statement to act as a “type guard”.
function logValueIfExists(value: string | undefined) {if (typeof value === 'string') {console.log(`Yay! ${value}!`);}}logValueIfExists('narrowing');// output: Yay! narrowing!
We invoked logValueIfExists() with a string variable, “narrowing”. Since the value is of type string, the code in the if statement will run and a new string will be logged to the console.
Example: Narrowing With Truthiness
In the example below, we changed the if statement slightly to check if value has any value that is “truthy” and doesn’t evaluate to a falsey value such as 0, false, or undefined.
function logValueIfExists(value: string | undefined) {value; // Type: string | undefinedif (value) {console.log(`Yay! ${value}!`);value; // Type: stringvalue.length; // Type: number}value.length;// Error: Object is possibly 'undefined'.}logValueIfExists('truthiness');// output: Yay! truthiness!let newValue;logValueIfExists(newValue);// newValue is "undefined"; nothing is logged.
Outside of the if statement, value is a union type (string | undefined) and is not narrowed, meaning that calling value.length won’t work. Inside the if statement, because value was narrowed to a string type, it now has a length property.
Contribute to Docs
- Learn more about how to get involved.
- Edit this page on GitHub to fix an error or make an improvement.
- Submit feedback to let us know how we can improve Docs.
Learn TypeScript on Codecademy
- A full-stack engineer can get a project done from start to finish, back-end to front-end.
- Includes 51 Courses
- With Professional Certification
- Beginner Friendly.150 hours
- Learn TypeScript, a superset of JavaScript that adds types to make the language scale!
- Intermediate.10 hours