1

I have a case:

interface State {
   Mark: boolean;
   Jane: boolean;
}

React.Component<{}, State> {

   state = {
      Mark: false,
      Jane: false,
   };

   fn = (name: string) => () => {
      this.setState({ [name]: true });
                     ^^^^^^^^^^
   }

   render () {
      return
        ['Mark', 'Jane'].map((name) => <div onClick={this.fn(name)}>{name}</div>);

}

Im getting error:

Argument of type '{ [x: string]: boolean; }' is not assignable 
to parameter of type 'State | Pick<State, "Mark" | "Jane">

I could do two separate functions for it, but I want to keep it generic. How could I make it generic so the error goes off?

1
  • The any type? Commented Jul 14, 2019 at 14:00

1 Answer 1

1

It turns out this is a limitation of the ts compiler itself. Check this issue for more on that: https://github.com/DefinitelyTyped/DefinitelyTyped/issues/26635

Now to solve your problem you can use setState with a callback version. Like bellow:

interface State {
    Mark: boolean;
    Jane: boolean;
}

type StateKeys = keyof State

class Test extends React.Component <{}, State > {

    state = {
        Mark: false,
        Jane: false,
    };

    fn = (name: StateKeys) => () => {
        this.setState(prev => ({ ...prev, [name]: true }));
   }

   render() {
       return ['Mark', 'Jane'].map((name: StateKeys) => <div onClick={this.fn(name)}>{name}</div>);

    }
}
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks, tried it but without destructuring state in callback function in setState :)
fn = (name: keyof State) => () => { this.setState({ [name]: true }); } should work

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.