jhipster реагирует на onChange состояние Аргумент типа '{[x: число]: любой; } 'не присваивается - PullRequest
0 голосов
/ 07 сентября 2018

Я новичок в React и у меня возникли некоторые проблемы с jsx при установке состояния в форме с двумя полями, которые делают вызов ajax для помещения объекта json (данных ответа) в field3 состояния. У меня есть следующее:

export interface IMyClassState {
    field1: string;
    field2: string;

    field3: object;
}

export class MyClass extends React.Component<IMyClassProps, IMyClassState> {
    state: IMyClassState = {
        field1: '',
        field2: '',

        field3: null
    }

    ...

    onSubmit = e => {
        e.preventDefault();
        ...
    }

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

    ...

    render() {
        return(
            <form onSubmit={this.onSubmit}>
                <input type="text" id="field1" name="field1" onChange={this.onChange}/>
                <input type="text" id="field2" name="field2" onChange={this.onChange}/>
            </form>
        );
    }
};

В примере только с двумя полями, я полагаю, у меня могут быть просто onChange s, например:

<input type="text" id="field1" name="field1" onChange={this.onChangeField1}/>
...

но если бы у меня было 100 полей, это было бы проблемой, поэтому я пытаюсь получить имя поля состояния непосредственно из e.target.name в моем onChange. Это, однако, дает мне ошибку:

Argument of type '{ [x: number]: any; }' is not assignable to parameter of type 'IMyClassState | Pick<IMyClassState, "field1" | "field2" 

Как мне избавиться от этой ошибки? Можно ли элегантно решить с одним вкладышем, как я пытался?

1 Ответ

0 голосов
/ 07 сентября 2018

Первая часть должна исправить тип e. Мы можем использовать запрос типа, чтобы сказать, что для typcript тип совпадает с onChange из input: onChange: JSX.IntrinsicElements['input']['onChange']

Вторая часть заключается в исправлении литерала объекта, который выводится как { [x: string]: string; }. В идеале мы могли бы сказать компилятору, что e.target.name является ключом IMyClassState

onChange: JSX.IntrinsicElements['input']['onChange'] = (e) => {
    this.setState({ [e.target.name as keyof IMyClassState]: e.target.value });
};

Приведенный выше код не работает, потому что машинопись будет по-прежнему выводить тип литерала объекта, равный { [x: string]: string; }. Единственный способ заставить компилятор вывести нужный нам тип - это привести e.target.name к конкретному полю IMyClassState.

onChange: JSX.IntrinsicElements['input']['onChange'] = (e) => {
    this.setState({ [e.target.name as "field1"]: e.target.value }); // Ok now
};

Хотя лгать компилятору не идеально, это самый простой вариант. Другой вариант - просто привести объект к литералу.

onChange: JSX.IntrinsicElements['input']['onChange'] = (e) => {
    this.setState({ [e.target.name]: e.target.value } as any as IMyClassState);
};
...