React Typescript: Argument of type '{ [x: number]: any; }' is not assignable to parameter of type
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.
lecham
Updated on June 26, 2022Comments
-
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'.
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 about 3 yearsCan you explain "...this.state"
-
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.