Typing Dynamic Object Keys With TS

In JavaScript or React, it’s common that we need to update a value on an object dynamically. Meaning that we wont’ be sure which key of this object we will update. Here’s a very common example:

const updateValue = (name, value) => this.setState({ [name]: value });

Here we create a re-usable function that will accept name used to target the key of the object and a value argument which will be used to as the update value. The problem is TypeScript needs to be told that the name should be a key of our State type and the value should match that key’s type.

Here’s a sample state:

interface State {
id: string;
name: string;
operator: boolean;
isFormValid: boolean;
};

To do this, we need to apply a couple advanced TS typings. We can use generics and the keyof and extends keyword to help us here.

const updateValue: <T extends keyof State, K extends State[T]> = (name: T, value: K): void => this.setState({ [name]: value });

Using the generic with these keywords,T extends keyof State , tells TS that T should be one of the keys of the State interface (id, name, etc…). Then the K extends State[T] let’s typescript know that K ‘s type should equal that of State[T] (this is simply bracket notation).

Now we have type checking on this function!