TypeOfNaN

Making Every Object Property Nullable in Typescript

Nick Scialli
March 18, 2021

New — Check out my free newsletter on how the web works!

I find it interesting which utility types the Typescript languages has adopted and which it hasn’t. For example, NonNullable is a built-in utility type but Nullable is not.

In this post, we’ll quickly write our own Nullable utility type that will allow any object propert to be nullable.

What We’re Trying to Do

A quick example of what we’re trying to do: let’s say we have a Person type:

type Person = {
  name: string;
  email: string;
  age: number;
  admin: boolean;
};

But perhaps we have an interface that we know might give us any subset of these object properties as null, so we’d like to quickly derive a type like this:

type NullablePerson = {
  name: string | null;
  email: string | null;
  age: number | null;
  admin: boolean | null;
};

We might hope that Typescript has a built-in Nullable type but, to our dismay, it doesn’t!

Rolling Your Own Nullable Utility Type

Fortunately, a Nullable utility type is only one line long:

type Nullable<T> = { [K in keyof T]: T[K] | null };

And the way we might use it with our Person type is like this:

const nullablePerson: Nullable<Person> = {
  name: 'Daffodil',
  email: null,
  age: null,
  admin: true,
};

One Step Further: Deeply Nullable

Perhaps we have a use case where we want our nullable type to be deep, meaning that any number of levels down the object should be nullable.

Let’s modify our Person type to have another level of properties:

type Person = {
  name: string;
  email: string;
  age: number;
  admin: boolean;
  dog: {
    name: string;
    age: number;
  };
};

To make this deeply nullable, we can simple recursively call the Nullable type on its own properties:

type DeepNullable<T> = {
  [K in keyof T]: DeepNullable<T[K]> | null;
};

And now if we implement this on our new Person type, we can see that our object can be nullable all the way down.

const nullablePerson: DeepNullable<Person> = {
  name: 'Daffodil',
  email: null,
  age: null,
  admin: true,
  dog: {
    name: 'Fido',
    age: null,
  },
};

Now we can use this utility type wherever we need and, with any luck, Typescript may add it as a built-in type someday!

🎓 Learn how the web works

Over my 20 year career in tech, I have noticed that an often-neglected part of interview prep is learning to explain technical concepts clearly. In my free newsletter, How the Web Works, I provide simple, bite-sized explanations for various web topics that you can use in your interview prep (or just to gain a better understanding of the web).

Enter your email below to get started. It's free and you can unsubscribe at any time. You won't regret it!

Nick Scialli

Nick Scialli is a senior UI engineer at Microsoft.

© 2024 Nick Scialli