React Typescript: Argument of type '{ [x: number]: any; }' is not assignable to parameter of type

14,263

Solution 1

You need to tell Typescript that your object will have one or more property from IAddPlayerFormState, but not necessarily all properties. You can do it like this:

public onChange(event: { target: { name: any; value: any; }; }) {
  const newState = { [name]: value } as Pick<IAddPlayerFormState, keyof IAddPlayerFormState>;
  this.setState(newState);
  console.log("On Change!");
}

Solution 2

Using this syntax got rid of the error for me:

const myFunction = (e) => {
    return this.setState({...this.state, [e.target.id]: e.target.value});
}

Solution 3

Your state shape is this:

interface IAddPlayerFormState {
  playerName: string;
  isDisabled: boolean;
}

and you are calling setState with this:

{any: any}

You can change only values: playerName and isDisabled not any. If you rewrite function signature as

public onChange(event: { target: { name: "playerName"|"isDisabled"; value: any; }; })

or better

public onChange(event: { target: { name: keyof IAddPlayerFormState ; value: any; }; })

it should be ok for typescript. Btw this code will not work though. Change input name :). I hope this answer is clear, if not i will edit that.

Share:
14,263
lecham
Author by

lecham

Updated on June 26, 2022

Comments

  • lecham
    lecham almost 2 years

    I added onChange method in my project(React, TS, Mobx), but I am getting an error: Argument of type '{ [x: number]: any; }' is not assignable to parameter of type

    I am new to TypeScript and not sure why it's happening. What can be the problem?

    (parameter) event: {
        target: {
            name: any;
            value: any;
        };
    }
    

    Argument of type '{ [x: number]: any; }' is not assignable to parameter of type 'IAddPlayerFormState | ((prevState: Readonly, props: Readonly) => IAddPlayerFormState | Pick | null) | Pick<...> | null'.

    enter image description here

    import React, { Component } from 'react';
    import ViewStore from '../../../store/ViewStore';
    import { TextField } from './../../../utils';
    
    interface IAddPlayerFormProps {
      viewStore?: ViewStore; // Optional ViewStore
    }
    
    interface IAddPlayerFormState {
      playerName: string;
      isDisabled: boolean;
    }
    
    class AddPlayerForm extends Component<IAddPlayerFormProps, IAddPlayerFormState> {
      constructor(props: Readonly<IAddPlayerFormProps>) {
        super(props);
    
        this.state = {
          isDisabled: false,
          playerName: '',
        };
      }
    
      public onChange(event: { target: { name: any; value: any; }; }) {
        this.setState({ [event.target.name]: event.target.value });
        console.log('On Change!');
      }
    
      public handleSubmit = () => {
        console.log('On submit!');
      }
    
      public render() {
        const { isDisabled } = this.state;
    
        return (
          <form onSubmit={this.handleSubmit}>
            <TextField
              type="text"
              name="name"
              value={name}
              placeholder="Add player"
              onChange={this.onChange}
              disabled={isDisabled}
            />
    
            <input type="submit" />
          </form>
        );
      }
    }
    
    export default AddPlayerForm;
    
  • JayC
    JayC about 3 years
    Can you explain "...this.state"
  • Amartya Mishra
    Amartya Mishra about 3 years
    @Jesse sure, ...this.state will expand/destructure the state object, then you are adding more objects to/modifying the destructured object. Finally, you take all of this and assign it to the current state using this.setState.