Preact: (TypeScript) Why can't I setState with an object containing the keys of my state type

Created on 16 Jul 2019  路  6Comments  路  Source: preactjs/preact

Why doesn't this work:

export interface IState {
    username: string;
    password: string;
}

// ...

private onInputChange(e: Event, field: keyof IState) {
    const target = e.target as HTMLInputElement;
    this.setState({ [field]: target.value });
}

image

Am I incorrect in thinking this should work? field is by definition one of the keys of IState, so defining an object containing only field as keys should be a valid IState object. Is there an issue with the preact type declarations, or have I misunderstood something?

Most helpful comment

This seems to be cause as it did not match Pick<State, keyof State>, so it was trying to match explicitly with State, when it should have been Partial<State>.

All 6 comments

That is an issue with TypeScript itself and not our typings. You can reproduce that issue in the official TypeScript playground: http://www.typescriptlang.org/play/#code/KYDwDg9gTgLgBASwHY2FAZgQwMbDgSQGUZNU4BvAKDhrgFcBnNJTAW2AC44GYpkBzANzVaYTAwYB3aABMuPPkiGUAvpUro6SbDAQQkcffiRg6MAMIALTEuAAKTnACiAN2AoANHHQJgAGzk4AGtgAE8IdAJiUmAASgoRGmx9HjgSKH5geABeOGAAOnTM+HE4AAkAFQBZABljUxgnP2B2FGFabizo1DtyOABtH38ZAF0uIqz8l0w-OjwVWOE1DS0dPQMmGG77HhiuIhJUeKoOgHpTuCQICDBVIA

You should post this at the TypeScript issue tracker 馃檪

@marvinhagemeister Ok thanks. Do you have any suggestions for how to implement such a function? Basically my state object has multiple text properties, and I don't want to have to add a mostly identical function for every event handler. Do I basically have to hack around it with as any?

After having a closer look I had an error in my sample snippet. Looks like we're indeed missing a Partial declaration in our types.

cc @pmkroeker

This is the updated sample: http://www.typescriptlang.org/play/#code/KYDwDg9gTgLgBASwHY2FAZgQwMbDgSQGUZNU4BvAKDhrgFcBnNJTAW2AC44GYpkBzANzVaYTAwYB3aABMuPPkiGUAvpUro6SbDAQQkcffiRg6MAMIALTEuAAKTnACiAN2AoANHHQJgAGzk4AGtgAE8IdAJiUmAASgoRGmx9HjgSKH5geABeOGAAOnTM+HE4AAkAFQBZABljUxgnP2B2FGFabizo1DtyOABtH38ZAF0uIqz8l0w-OjwVWOE1DS0dPQMmGG77HhiuAAVMWAQZgB4iElQAPniqDoB6e7gkCAgwVSA

@marvinhagemeister Does that mean my original example should work after modifying preact's types?

Interesting. I think I played around with using Partial and it had some other side effects that I didn't like, also, the React typings don't use Partial for setState but Pick like ours do. Will investigate.
Related typing in react

This seems to be cause as it did not match Pick<State, keyof State>, so it was trying to match explicitly with State, when it should have been Partial<State>.

Was this page helpful?
0 / 5 - 0 ratings