Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Property is missing in type '{ [x: string]: string; }'

In this react app there is a form with a few input fields. These fields all use this.handleChange with the onChange attribute.

private handleChange = (event: React.FormEvent<HTMLInputElement>) => {
    let target = event.target as HTMLInputElement;
    this.setState({
        [target.name]: target.value
    });
};

The typescript error I get is:

ERROR in [at-loader] ./src/components/FormSubmitHighScore.tsx:43:23 
TS2345: Argument of type '{ [x: string]: string; }' is not assignable to parameter of type 'Pick<State, "first_name" | "last_name" | "email_address" | "school_name" | "region" | "submitted">'.
Property 'first_name' is missing in type '{ [x: string]: string; }'.

So by setting the state name field dynamically (based on what input is being used) this Typescript error gets triggered (but it does work in the browser).

How would I specify a correct type in this context?

like image 657
Floris Avatar asked Sep 22 '17 09:09

Floris


3 Answers

Unfortunately until these bugs are fixed - you have to go with some ugly workarounds like:

this.setState({
    [target.name]: target.value
} as any);
like image 61
Amid Avatar answered Oct 18 '22 17:10

Amid


To avoid "any" linter warning I use:

this.setState({
  [target.name]: target.value
} as Pick<State, keyof State>);
like image 13
Martin Avatar answered Oct 18 '22 19:10

Martin


Passing a function to setState works too. My guess is that it is because you are spreading state, so typescript knows it has all the properties of state.

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

I was getting a similar error to what you were getting. Here is my implementation for a change handler:

  onChange = (name: keyof ComponentState, value: any) => {
    this.setState(state => ({
      ...state,
      [name]: value,
    }));
  };
like image 2
pizzarob Avatar answered Oct 18 '22 19:10

pizzarob