Deep Object Change Handlers in Typescript

nas5w

Nick Scialli (he/him)

Posted on May 22, 2020

Deep Object Change Handlers in Typescript

Typescript's ability to deeply-type objects is incredibly handy: it gives you confidence that you're accessing the right keys on an object and that you're using those keys as the right types. However, this typing doesn't come for free: it can add complexity to things like change handlers. In this post, we'll write a deep object change handler that both allows us to specify deep object types and satisfies the Typescript compiler.

A Sample Deep Object Type

Let's use the following Settings type as an example. It contains some visual settings about our app and some information about our user.

type Settings = {
  display: {
    mode: "light" | "dark";
  };
  user: {
    name: string;
    age: number;
    admin: boolean;
  };
};
Enter fullscreen mode Exit fullscreen mode

We can then create a sample object that satisfies this type. Let's use the following example.

const settings: Settings = {
  display: {
    mode: "dark",
  },
  user: {
    name: "Betty",
    age: 27,
    admin: false,
  },
};
Enter fullscreen mode Exit fullscreen mode

Writing a Change Handler

So what if we want a change handler that will change any property two levels deep in this object? The secret lies in the use of Generics. We can specify that our key is of type K, where K extends keyof Settings. Likewise, we can specify that our subkey is of type S, where S extends keyof Settings[K].

Putting this all together, we get the following change handler!

const updateSettings = <
  K extends keyof Settings, 
  S extends keyof Settings[K]
>(
  key: K,
  subkey: S,
  value: Settings[K][S]
): Settings => {
  const newSettings = {
    ...settings,
    [key]: {
      ...settings[key],
      [subkey]: value,
    },
  };

  return newSettings;
};
Enter fullscreen mode Exit fullscreen mode

And there we have it: a framework by which we can update deep types and keep our Typescript compiler happy!

πŸ’– πŸ’ͺ πŸ™… 🚩
nas5w
Nick Scialli (he/him)

Posted on May 22, 2020

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related