Narrowing in TypeScript

Narrowing refers to the process of reducing the type of a variable from a broader type to a more specific type within a certain code block or context.

Narrowing in TypeScript

TypeScript variables or functions can have types which is Union of multiple types. In order for TypeScript to refine the type checking and predict accurate types, we need to help TypeScript by placing some conditional statements called Type Guards and this process of refining the types is called Narrowing. Type Guars help the TypeScript compiler understand precisely what the type of a variable is at a given point in the code. Narrowing refers to the process of reducing the type of a variable from a broader type to a more specific type within a certain code block or context.

Let's look at an example from official TypeScript documentation.

function padLeft(padding: number | string, input: string): string {
 
}

This function takes two parameters , first parameter is number of spaces or padding on the left side of the text which is in second parameter. First parameter has a union type or number or string. If it was a string means it contains spaces and if it was a number, we need to add that many spaces on the left side of the input parameter. Let's try to implement this.

function padLeft(padding: number | string, input: string): string {
  return " ".repeat(padding) + input;
}

Here in this case TypeScript will give us an error.

Argument of type 'string | number' is not assignable to parameter of type 'number'.
Type 'string' is not assignable to type 'number'.

We need to use a Type Guard in order to get the actual expected type which is string.

So we can re-write our code to something like this.

function padLeft(padding: number | string, input: string): string {
  if (typeof padding === "number") {
    return " ".repeat(padding) + input;
  }
  return padding + input;
}

Here TypeScript sees typeof padding === "number" as a Type Guard. TypeScript follows possible paths of execution that our programs can take to analyze the most specific possible type of a value at a given position. It looks at these special checks (Type Guards) and assignments. In many code editors you can observe these types as they change from one type to another in these blocks of codes.

Here are some common techniques TypeScript uses to narrow down the possible types.

typeOf Type Guards

typeOf operator can help TypeScript to get the type of a variable if it is one of the following basic types, including string, number , bigint, boolean, symbol, undefined, object and function.

instanceOf Narrowing

instanceOf operator helps TypeScript to understand if an object is an instance of a particular class.

Truthiness

Typescript make use of statements which result in true/false values to predict the types. Statements like && , ||, ! can help TypeScript make these decisions.

Equality Narrowing

TypeScript also uses switch statements and equality checks like ===!====, and != to narrow types.

in operator Narrowing

JavaScript in operator can also be used to determine if an object or its prototype chain has a property with a name. TypeScript takes this into account as a way to narrow down potential types.

Assignment Operators

TypeScript also used the assignment operator = to determine the type of a variable. TypeScript looks at the right side of the assignment and narrows the left side appropriately.

Control Flow Analysis

Control statement like if and while also help TypeScript determine the accurate types in certain conditional code blocks.

Type Predicates

Type predicates like test is string also called user defined Type Guards. TypeScript use these statements to narrow down the types.

There is lot more techniques used by TypeScript to determine the most accurate types during the compile time. Check out the official TypeScript documentation for detailed information with examples on above mentioned and other ways it used to narrow down the types.

Documentation - Narrowing
Understand how TypeScript uses JavaScript knowledge to reduce the amount of type syntax in your projects.
Liked it ?

Read more