Я ищу лучший способ управления состоянием формы в React с помощью TypeScript.Моя простая форма имеет два значения: login
и password
поля.Я реализую интерфейс IState
для состояния формы и метод DRY handleChange
для сохранения нового значения в состоянии без воссоздания функции при каждом выполнении render()
.
interface IState {
login: string;
password: string;
}
class LoginForm extends React.Component<{}, IState> {
public state = {
login: "",
password: "",
};
public render() {
const { login, password } = this.state;
return (
<form>
<input name="login" value={login} onChange={this.handleChange}/>
<input name="password" value={password} onChange={this.handleChange} type="password"/>
</form>
);
}
private handleChange = (e: React.FormEvent<HTMLInputElement>) => {
const { name, value } = e.currentTarget;
const n = name as keyof IState;
// @ts-ignore
this.setState({
[n]: value,
});
}
}
Я использую атрибут name
нативного HTML для хранилищаИмя поляПеременная n
будет иметь только значение login
или password
.Любое другое значение невозможно.Могу ли я сказать TypeScript, что переменная n
имеет тип "login" | "password"
литералы?TypeScript рассматривает n
как string
переменную типа, даже если я использую:
const n = name as keyof IState;
или
const n = name as "login" | "password";
Затем, когда я удаляю // @ts-ignore
, я получаю ошибку:
Type error: Argument of type '{ [x: string]: string; }' is not assignable to parameter of type 'IState | Pick<IState, "login" | "password"> | ((prevState: Readonly<IState>, props: Readonly<IProps>) => IState | Pick<IState, "login" | "password"> | null) | null'.
Type '{ [x: string]: string; }' is missing the following properties from type 'Pick<IState, "login" | "password">': login, password TS2345
но без ошибок при жестком коде:
const n = "login";
Есть ли способ заставить "login" | "password"
тип переменной n
?Или любое другое решение для DRY handleChange
без проблем оптимизации и чистого TypeScript?