Skip to content

Instantly share code, notes, and snippets.

@wyqydsyq
Created February 20, 2020 01:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save wyqydsyq/143fdb0732830f22e182f9c1cb1c1101 to your computer and use it in GitHub Desktop.
Save wyqydsyq/143fdb0732830f22e182f9c1cb1c1101 to your computer and use it in GitHub Desktop.
React updateStatePair

updateStatePair

Ever got tired of repeating this pattern everywhere when you want to update just one key/value pair in your state? Noticed the key/values you set in setState aren't typechecked and wish you had type safety when doing this kind of thing?

setState(prevState => ({ ...prevState, [key]: value })
// `key` and `value` can be anything here, does not have to match the type of your State

updateStatePair to the rescue!

It uses generics to infer the type of your state, restricting the key and value arguments to be allowed keys of your state and allowed values of your key!

Example:

// given this state:
const [x, setX] = React.useState({
  foo: true,
  bar: false,
  hello: 'world'
});
  
updateStatePair(setX, 'foo', false);
// x.foo === false

updateStatePair(setX, 'fakekey', false);
// Argument of type '"fakekey"' is not assignable to parameter of type '"bar" | "foo" | "hello"'.ts(2345)

updateStatePair(setX, 'hello', false);
// Argument of type 'false' is not assignable to parameter of type 'string'.ts(2345)
function updateState<S, NS>(setState: React.Dispatch<React.SetStateAction<S>>) {
return (newState: NS) => setState(prevState => ({ ...prevState, ...newState }));
}
function updateStatePair<S, K extends keyof S, V extends S[K]>(
setState: React.Dispatch<React.SetStateAction<S>>,
key: K,
value: V
) {
return updateState(setState)({ [key]: value });
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment