Typescript устанавливает ключ объекта по переменной на интерфейсе - PullRequest
0 голосов
/ 30 апреля 2020

Похоже на это в Javascript.

У меня есть компонент React с интерфейсом:

interface IState {
  email: string,
  passwordOne: string,
  passwordTwo: string,
  error: {}
}

class SignUpForm extends React.Component<{}, IState> {
  constructor(props) {
    super(props)
  }
...

onChange = event => {
  this.setState({ [event.target.name]: event.target.value });
};
...

<input type="email" placeholder="Your email address" name="email"
    value={email} onChange={this.onChange}/>
...

SetState жалуется, что аргумент типа Нельзя назначить IState.

Есть ли способ исправить это или это невозможно в TS?

Ответы [ 2 ]

2 голосов
/ 30 апреля 2020

Вы никогда не должны распространять this.state в вызове setState, потому что setState происходит асинхронно, и вы можете столкнуться с некоторыми существенными и сложными для отслеживания проблемами состояния гонки.

Если вы хотите использовать хакерский способ обмана систему типов, вы можете использовать:

  onChange = (event: React.ChangeEvent<HTMLInputElement>) => {
    let key = event.target.name;
    let value = event.target.value;
      this.setState(state=>({...state, [key]: value }));
  };

или просто игнорировать ошибку машинописного текста, поскольку это, по сути, то, что вы делаете:

  onChange = (event: React.ChangeEvent<HTMLInputElement>) => {
    let key = event.target.name;
    let value = event.target.value;
    // @ts-ignore
    this.setState({[key]: value });
  };

Если вы хотите решить ее без проблем с типами, используйте решение из этого комментария: https://github.com/Microsoft/TypeScript/issues/13948#issuecomment -412365629

private handleChange = <T extends keyof IState>(event: React.ChangeEvent<HTMLInputElement>) => {
  const newState = {
    [event.target.name]: event.target.value,
    // keyNotInState: '42', -> would throw a compile time error
    // numericKeyInState: 'assigning wrong type' -> would throw a compile time error
  };
  this.setState(newState as { [P in T]: IState[P]; });
}
1 голос
/ 30 апреля 2020

Я полагаю, что вы можете взломать его на такую ​​работу ... если произойдет сбой, поскольку IState ожидает все свойства, а вы просто устанавливаете одно.

onChange = event => {
  this.setState({ ...this.state, [event.target.name]: event.target.value });
};
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...