Typescript generic state change function type casting error

后端 未结 2 1888
后悔当初
后悔当初 2021-01-24 03:52

I\'m creating a generic function to change the state.

The error message:

TS2345: Argument of type \'() => { [x:string]: string }\' is not assignable          


        
相关标签:
2条回答
  • 2021-01-24 04:03

    There are a few solutions:

     this.setState<never>({ [name]: value } as Partial<IInputStates>)
    

    Or

     this.setState({ [name]: value } as Pick<IInputStates, keyof IInputStates>);
    

    There is an open issue in git, take a look: cannot setState with dynamic key name type-safe

    0 讨论(0)
  • 2021-01-24 04:23

    Using types won't prevent the errors property from being changed as the type checking applies at compile time only. This will still run as plain old dynamic JavaScript when it gets to the browser where anything goes.

    If you want to restrict the properties the change function acts on you need to check the property name e.g. against an array of allowed values.

    As a side note your inputs are missing the name property.

     render() {
        const { url, errors } = this.state;
        return (
          <form>
            <input type="text" name="url" value={url} onChange={this.change} />
            <input type="text" name="name" value={name} onChange={this.change} />
          <form>
        )
      }
    
      change = (event:React.ChangeEvent<HTMLInputElement>) => {
        const name = event.target.name;
        const value = event.target.value;
    
        if (!isValidProperty(name)) return;
    
        this.setState({ [name]: value } as Partial<IInputStates>)
      }
    
      // Dummy instance to force a compile warning and ensure we capture all the property names
      const inputExample: IInputStates = { url: '' };
      const inputKeys = Object.keys(inputExample);
    
      function isValidProperty(name: string): name is keyof IInputStates {
        return inputKeys.includes(name);
      }
    
    0 讨论(0)
提交回复
热议问题