Published on

Narrowing in Typescript

Authors
  • avatar
    Name
    Simon Kurbiel
    Twitter

Introduction

Welcome! This is a basic introduction into narrowing in javascript.

The typeof type guards in javascript.

These are the types that javascipt supports, although the list is not exhaustive.

  • "string"
  • "number"
  • "boolean"
  • "undefined"
  • "object"
  • "function"

Now syppose you have a function with one parameter. The goal is to print every thing in there. The code can look something like this.

const printAll = (strs: string | string[] | null) => {
  if (typeof strs === 'object') {
    for (const s of strs) {
      console.log(s)
    }
  } else if (typeof strs === 'string') {
    console.log(strs)
  } else {
    // do nothing
  }
}

Now, it might not be very obvious, but this will raise an error in typescript. This is because null is also an object. This is one of the quirks of the language. To by pass this we can do truthiness narrowing

Truthiness narrowing

if you have experience with low level language such as C, you will be familiar with checking whether a value is 0 which is falsy, whereas any other value is truthy. Javascript follows the same format. Any of these types will be identified as falsy (list is not exhaustive)

  • ""
  • undefined
  • null
  • 0
  • NaN

Refine code

Now that we know which types will constitute a falsy value, lets refactor the code.

const printAll = (strs: string | string[] | null) => {
  if (strs && typeof strs === 'object') {
    for (const s of strs) {
      console.log(s)
    }
  } else if (typeof strs === 'string') {
    console.log(strs)
  } else {
    // do nothing
  }
}

The only thing needed in this case, was to make sure that strs was both truthy and an object