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