TypeOfNaN

How to Make One Function Argument Dependent on Another in Typescript

Nick Scialli
September 05, 2020

typescript function

Typescript can be incredibly helpful when we use some of its more advanced features. In this post, we specify the type of one function argument based on the type of another.

A Scenario

Let’s say we have a change handler for an object’s properties. In plain JavaScript, this change handler might look something like this:

const user = {
  name: 'Daffodil',
  age: 27,
  admin: false,
};

const changeUser = (key, value) => {
  user[key] = value;
};

Simple enough! But what if we want to do something similar in Typescript?

A Naive Approach

Let’s take a naive approach. We might assume the key will be a keyof our User type and the value might be something like User[typeof key].

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

const user = {
  name: 'Daffodil',
  age: 27,
  admin: false,
};

const changeUser = (key: keyof User, value: User[typeof key]) => {
  user[key] = value;
};

Alas, this doesn’t work. We get an error like this:

type error

Basically, the Typescript compiler doesn’t quite understand how to narrow the type of value based on the provided key.

The Solution: Generics

The solution to our problem is Generics! We can specify a generic, K, that is a keyof User. Then, our value can be of type User[K].

Here’s how this works:

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

const user = {
  name: 'Daffodil',
  age: 27,
  admin: false,
};

const changeUser = <K extends keyof User>(key: K, value: User[K]) => {
  user[key] = value;
};

Great! We no longer have a compilation error and our value argument will now be narrowed based on the key argument. To see this in action, let’s take a look at different scenarios where our compiler does and doesn’t get mad at us.

typescript warnings

We see that our Typescript compiler is okay when we specify the correct types for each key, but it shows errors when the wrong types are provided for a particular key!

If you'd like to support this blog by buying me a coffee I'd really appreciate it!

Nick Scialli

Nick Scialli is a senior UI engineer at Microsoft.

© 2024 Nick Scialli