score:627

Accepted answer

Generally event handlers should use e.currentTarget.value, e.g.:

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

You can read why it so here (Revert "Make SyntheticEvent.target generic, not SyntheticEvent.currentTarget.").

UPD: As mentioned by @roger-gusmao ChangeEvent more suitable for typing form events.

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

score:0

import { NativeSyntheticEvent, TextInputChangeEventData,} from 'react-native';



  // Todo in java script
 const onChangeTextPassword = (text : any) => {
    setPassword(text);
  }
    

// Todo in type script use this

  const onChangeTextEmail = ({ nativeEvent: { text },}: NativeSyntheticEvent<TextInputChangeEventData>) => {
    console.log("________ onChangeTextEmail _________ "+ text);
    setEmailId(text);
  };


 <TextInput
          style={{ width: '100%', borderBottomWidth: 1, borderBottomColor: 'grey', height: 40, }}
          autoCapitalize="none"
          returnKeyType="next"
          maxLength={50}
          secureTextEntry={false}
          onChange={onChangeTextEmail}
          value={emailId}
          defaultValue={emailId}
          
        />

  

score:1

  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
  }

And make sure you have "lib": ["dom"] in your tsconfig.

score:1

This works for me also it is framework agnostic.

const handler = (evt: Event) => {
  console.log((evt.target as HTMLInputElement).value))
}

score:3

This is when you're working with a FileList Object:

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;
}}

score:3

Thanks @haind

Yes HTMLInputElement worked for input field

//Example
var elem = e.currentTarget as HTMLInputElement;
elem.setAttribute('my-attribute','my value');
elem.value='5';

This HTMLInputElement is interface is inherit from HTMLElement which is inherited from EventTarget at root level. Therefore we can assert using as operator to use specific interfaces according to the context like in this case we are using HTMLInputElement for input field other interfaces can be HTMLButtonElement, HTMLImageElement etc.

https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement

For more reference you can check other available interface here

score:3

You no need to type if you do this:

<input onChange={(event) => { setValue(e.target.value) }} />

Because if you set a new value with the arrow function directly in the html tag, typescript will understand by default the type of event.

score:5

Here is a way with ES6 object destructuring, tested with TS 3.3.
This example is for a text input.

name: string = '';

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

score:6

An alternative that has not been mentioned yet is to type the onChange function instead of the props that it receives. Using React.ChangeEventHandler:

const stateChange: React.ChangeEventHandler<HTMLInputElement> = (event) => {
    console.log(event.target.value);
};

score:8

When using Child Component We check type like this.

Parent Component:

export default () => {

  const onChangeHandler = ((e: React.ChangeEvent<HTMLInputElement>): void => {
    console.log(e.currentTarget.value)
  }

  return (
    <div>
      <Input onChange={onChangeHandler} />
    </div>
  );
}

Child Component:

type Props = {
  onChange: (e: React.ChangeEvent<HTMLInputElement>) => void
}

export Input:React.FC<Props> ({onChange}) => (
  <input type="tex" onChange={onChange} />
)

score:10

I use something like this:

import { ChangeEvent, useState } from 'react';


export const InputChange = () => {
  const [state, setState] = useState({ value: '' });

  const handleChange = (event: ChangeEvent<{ value: string }>) => {
    setState({ value: event?.currentTarget?.value });
  }
  return (
    <div>
      <input onChange={handleChange} />
      <p>{state?.value}</p>
    </div>
  );
}

score:12

we can also use the onChange event fire-up with defined types(in functional component) like as follows:

 const handleChange = (
    e: React.ChangeEvent<HTMLTextAreaElement | HTMLInputElement>
  ) => {
        const name = e.target.name;
        const value = e.target.value;
};

score:13

The target you tried to add in InputProps is not the same target you wanted which is in React.FormEvent

So, the solution I could come up with was, extending the event related types to add your target type, as:

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>>;
}

Once you have those classes, you can use your input component as

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

without compile errors. In fact, you can also use the first two interfaces above for your other components.

score:17

as HTMLInputElement works for me

score:70

You can do the following:

import { ChangeEvent } from 'react';

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

score:178

the correct way to use in TypeScript is

  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} />
        ...
    );
  }

Follow the complete class, it's better to understand:

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;

Related Query

More Query from same tag