Pick<S, K> type with dynamic/computed keys

So after doing more research I can provide a little more context on what is happening in the above code.

When you do something like const name = 'Bob' the type of the variable name is 'Bob' not string. However, if you replace the const with a let (let name = 'Bob') the variable name will be of type string.

This concept is called "widening". Basically, it means that the type system tries to be as explicit as possible. Because const can not be reassigned TypeScript can infer the exact type. let statements can be reassigned. Thus, TypeScript will infer string (in the above example) as the type of name.

The same is happening with const key = e.currentTarget.name as keyof Person. key will be of (union) type "name"|"age", which is exactly what we want it to be. But in the expression this.setState({ [key]: value }); variable key is (incorrectly) widened to a string.


tl;dr; It seems like there is a bug in TypeScript. I posted the issue to the Github repo and the TypeScript team is investigating the problem. :)

As a temporary workaround you can do:

this.setState({ [key as any]: value });

The answer from Sebastian no longer works for me (though at one stage it did). I now do the following until it is resolved in Typescript core (as per the issue listed in Sebastians answer):

  handleUpdate (e:React.SyntheticEvent<HTMLInputElement>) {
    const newState = {};
    newState[e.currentTarget.name] = e.currentTarget.value;
    this.setState(newState);
  }

It's lame, but it works