typescript: using the nonnullable utility to avoid bugs



~2 min read


335 words

When writing an interface for a function, it’s common to want to allow a range of types. This can often be communicated with a generic.

For example, imagine a function toString:

function toString<T>(x: T): string {
  return x.toString()

Our function will take a type T and returns a string. In Javascript, the Object prototype includes a toString method and (almost) everything in Javascript is an object. Typescript is now smart enough to know that not every T has a toString method on its prototype, so the compiler will complain about this function now, but it wouldn’t about a variant - for example:

function toString<T>(x: T): string {
  return String(x)

In this case, we’re saying we’ll take any T and convert it to a string. However, interestingly, this includes null and undefined:


These work by returning "undefined" and "null" - which probably isn’t what we want.

One way to solve this is with the NonNullable utility type1:

function totalToString<T extends {}>(x: NonNullable<T>): string {
  return x.toString()

Now, when we try to pass undefined or null into our function, Typescript will alert us that they’re not allowed and so we shouldn’t call the function:


In this way, we’ve gone from a Partial function, one in which all allowed inputs may not return a value, into a Total function, one which terminates in a value for all possible inputs.

We’ve also done it in a way where we know up front whether we’re passing in undefined or null and can handle that - rather than getting a string of "undefined" that looks just like any other string.

H/t to Lauren Tan for her 2018 DotJS talk Learning To Love Type Systems which introduced me to the NonNullable utility as well as the distinction between Partial and Total functions.


  • 1 Other Utility functions include Partial and Omit which I’ve written about previously as immensely helpful.

Hi there and thanks for reading! My name's Stephen. I live in Chicago with my wife, Kate, and dog, Finn. Want more? See about and get in touch!