Typescript input onchange event.target.value

В моем приложении реакции и typescript я использую: onChange={(e) => data.motto = (e.target as any).value}.

Как правильно определить типизацию для класса, так что мне не пришлось бы взломать мой путь вокруг системы типов с помощью any?

export interface InputProps extends React.HTMLProps<Input> {
...

}

export class Input extends React.Component<InputProps, {}> {
}

Если я поставлю target: { value: string };, я получаю:

ERROR in [default] /react-onsenui.d.ts:87:18
Interface 'InputProps' incorrectly extends interface 'HTMLProps<Input>'.
  Types of property 'target' are incompatible.
    Type '{ value: string; }' is not assignable to type 'string'.

Ответ 1

Обычно обработчики событий должны использовать e.currentTarget.value, например:

onChange = (e: React.FormEvent<HTMLInputElement>) => {
    const newValue = e.currentTarget.value;
}

Вы можете прочитать, почему это так, здесь (Отменить "Сделайте SyntheticEvent.target универсальным, а не SyntheticEvent.currentTarget.").

UPD: Как уже упоминалось @roger-gusmao ChangeEvent, больше подходит для ввода событий формы.

onChange = (e: React.ChangeEvent<HTMLInputElement>)=> {
   const newValue = e.target.value;
}

Ответ 2

правильный способ использования в TypeScript

  handleChange(e: React.ChangeEvent<HTMLInputElement>) {
    // No longer need to cast to any - hooray for react!
    this.setState({temperature: e.target.value});
  }

  render() {
        ...
        <input value={temperature} onChange={this.handleChange} />
        ...
    );
  }

Следуйте за полным классом, лучше понять:

import * as React from "react";

const scaleNames = {
  c: 'Celsius',
  f: 'Fahrenheit'
};


interface TemperatureState {
   temperature: string;
}

interface TemperatureProps {
   scale: string;

}

class TemperatureInput extends React.Component<TemperatureProps, TemperatureState> {
  constructor(props: TemperatureProps) {
    super(props);
    this.handleChange = this.handleChange.bind(this);
    this.state = {temperature: ''};
  }

  //  handleChange(e: { target: { value: string; }; }) {
  //    this.setState({temperature: e.target.value});  
  //  }


  handleChange(e: React.ChangeEvent<HTMLInputElement>) {
    // No longer need to cast to any - hooray for react!
    this.setState({temperature: e.target.value});
  }

  render() {
    const temperature = this.state.temperature;
    const scale = this.props.scale;
    return (
      <fieldset>
        <legend>Enter temperature in {scaleNames[scale]}:</legend>
        <input value={temperature} onChange={this.handleChange} />
      </fieldset>
    );
  }
}

export default TemperatureInput;

Ответ 3

as HTMLInputElement работает для меня

Ответ 4

target, который вы пытались добавить в InputProps, не совпадает с target, который вам нужен, который находится в React.FormEvent

Итак, решение, которое я мог придумать, заключалось в расширении связанных с событиями типов для добавления вашего целевого типа, например:

interface MyEventTarget extends EventTarget {
    value: string
}

interface MyFormEvent<T> extends React.FormEvent<T> {
    target: MyEventTarget
}

interface InputProps extends React.HTMLProps<Input> {
    onChange?: React.EventHandler<MyFormEvent<Input>>;
}

Как только у вас есть эти классы, вы можете использовать свой компонент ввода как

<Input onChange={e => alert(e.target.value)} />

без ошибок компиляции. Фактически вы также можете использовать первые два интерфейса выше для ваших других компонентов.

Ответ 5

Мне повезло, я нашел решение. вы можете

import {ChangeEvent} из 'response';

а затем напишите код: e:ChangeEvent<HTMLInputElement>

Ответ 6

Вот способ разрушения объекта ES6, протестированный на TS 3.3.
Этот пример для ввода текста.

name: string = '';

private updateName({ target }: { target: HTMLInputElement }) {
    this.name = target.value;
}

Ответ 7

Это когда вы работаете с объектом FileList:

onChange={(event: React.ChangeEvent<HTMLInputElement>): void => {
  const fileListObj: FileList | null = event.target.files;
  if (Object.keys(fileListObj as Object).length > 3) {
    alert('Only three images pleaseeeee :)');
  } else {
    // Do something
  }

  return;
}}

Ответ 8

  function handle_change(
    evt: React.ChangeEvent<HTMLInputElement>
  ): string {
    evt.persist(); // This is needed so you can actually get the currentTarget
    const inputValue = evt.currentTarget.value;

    return inputValue
  }

И убедитесь, что в вашем tsconfig есть "lib": ["dom"].

Ответ 9

Вы можете определить тип "any" для e. onChange = {(e: any) = > data.motto = e.target.value}