typesafe select onChange event using reactjs and typescript

typescript select onchange event type
onchange event typescript angular
react-select onchange
react click event typescript
textfield onchange event type
onblur event typescript
react scroll event typescript
property 'value' does not exist on type 'eventtarget'

I have figured out how to tie up an event handler on a SELECT element using an ugly cast of the event to any.

Is it possible to retrieve the value in a type-safe manner without casting to any?

import React = require('react');

interface ITestState {
    selectedValue: string;
}

export class Test extends React.Component<{}, ITestState> {

    constructor() {
        super();
        this.state = { selectedValue: "A" };
    }

    change(event: React.FormEvent) {
        console.log("Test.change");
        console.log(event.target); // in chrome => <select class="form-control" id="searchType" data-reactid=".0.0.0.0.3.1">...</select>

        // Use cast to any works but is not type safe
        var unsafeSearchTypeValue = ((event.target) as any).value;

        console.log(unsafeSearchTypeValue); // in chrome => B

        this.setState({
            selectedValue: unsafeSearchTypeValue
        });
    }

    render() {
        return (
            <div>
                <label htmlFor="searchType">Safe</label>
                <select className="form-control" id="searchType" onChange={ e => this.change(e) } value={ this.state.selectedValue }>
                    <option value="A">A</option>
                    <option value="B">B</option>
                </select>
                <h1>{this.state.selectedValue}</h1>
            </div>
        );
    }
}

Since upgrading my typings to react 0.14.43 (I'm not sure exactly when this was introduced), the React.FormEvent type is now generic and this removes the need for a cast.

import React = require('react');

interface ITestState {
    selectedValue: string;
}

export class Test extends React.Component<{}, ITestState> {

    constructor() {
        super();
        this.state = { selectedValue: "A" };
    }

    change(event: React.FormEvent<HTMLSelectElement>) {
        // No longer need to cast to any - hooray for react!
        var safeSearchTypeValue: string = event.currentTarget.value;

        console.log(safeSearchTypeValue); // in chrome => B

        this.setState({
            selectedValue: safeSearchTypeValue
        });
    }

    render() {
        return (
            <div>
                <label htmlFor="searchType">Safe</label>
                <select className="form-control" id="searchType" onChange={ e => this.change(e) } value={ this.state.selectedValue }>
                    <option value="A">A</option>
                    <option value="B">B</option>
                </select>
                <h1>{this.state.selectedValue}</h1>
            </div>
        );
    }
}

React Typescript cheatsheet: form elements and onChange event , Quick cheat sheet with all the typings used for React forms. All the form React Typescript cheatsheet: form elements and onChange event types "optionA", ); return ( <select value={selectValue} onBlur={( ev: React. React’s version of the onchange event handler is the same, but camel-cased. If you’re using forms inside of a React component, it’s a good idea to understand how the onChange event handler works with forms, state, and how you can pass the value to a function. Event handlers are an important part of React.

I tried using React.FormEvent<HTMLSelectElement> but it led to an error in the editor, even though there is no EventTarget visible in the code:

The property 'value' does not exist on value of type 'EventTarget'

Then I changed React.FormEvent to React.ChangeEvent and it helped:

private changeName(event: React.ChangeEvent<HTMLSelectElement>) {
    event.preventDefault();
    this.props.actions.changeName(event.target.value);
}

typesafe sélectionner un événement onChange en utilisant reactjs , select> // Use cast to any works but is not type safe var unsafeSearchTypeValue = ((event.target) as any).value; console.log(unsafeSearchTypeValue); // in  Typescript input onchange event.target.value. In my react and typescript app, I use: onChange= { (e) => data.motto = (e.target as any).value}.

Update: the official type-definitions for React have been including event types as generic types for some time now, so you now have full compile-time checking, and this answer is obsolete.


Is it possible to retrieve the value in a type-safe manner without casting to any?

Yes. If you are certain about the element your handler is attached to, you can do:

<select onChange={ e => this.selectChangeHandler(e) }>
    ...
</select>
private selectChangeHandler(e: React.FormEvent)
{
    var target = e.target as HTMLSelectElement;
    var intval: number = target.value; // Error: 'string' not assignable to 'number'
}

Live demo

The TypeScript compiler will allow this type-assertion, because an HTMLSelectElement is an EventTarget. After that, it should be type-safe, because you know that e.target is an HTMLSelectElement, because you just attached your event handler to it.

However, to guarantee type-safety (which, in this case, is relevant when refactoring), it is also needed to check the actual runtime-type:

if (!(target instanceof HTMLSelectElement))
{
    throw new TypeError("Expected a HTMLSelectElement.");
}

[V2] [Typescript] ValueType<Option> is not exported. · Issue #2902 , The problem I'm using React-Select v2 in typescript and the onChange event handler has a first parameter with a the type ValueType which is  The change event is triggered on the <select> element, not the <option> element. However, that's not the only problem. The way you defined the change function won't cause a rerender of the component.

The easiest way is to add a type to the variable that is receiving the value, like this:

var value: string = (event.target as any).value;

Or you could cast the value property as well as event.target like this:

var value = ((event.target as any).value as string);

Edit:

Lastly, you can define what EventTarget.value is in a separate .d.ts file. However, the type will have to be compatible where it's used elsewhere, and you'll just end up using any again anyway.

globals.d.ts

interface EventTarget {
    value: any;
}

Typescript input onchange event.target.value, In my react and typescript app, I use: onChange={(e) => data.motto = (e.target as Learn more typesafe select onChange event using reactjs and typescript  With React JS and TypeScript I found that I prefer to use the arrow function with the onChange attribute on the input element. From there you can access the files and pass them to a function. In

it works:

type HtmlEvent = React.ChangeEvent<HTMLSelectElement>

const onChange: React.EventHandler<HtmlEvent> = 
   (event: HtmlEvent) => { 
       console.log(event.target.value) 
   }

TypeScript and React: Hooks, select> // Use cast to any works but is not type safe var unsafeSearchTypeValue = ((event.target) as any).value; console.log(unsafeSearchTypeValue); // in  When creating a form with React components, it is common to use an onChange handler to listen for changes to input elements and record their values in state. Besides handling just one input, a single onChange handler can be set up to handle many different inputs in the form.

Typescript react select onchange event, Check out how you can use hooks with TypeScript! Disclaimer: This is If you do , React will check if those values did change, and triggers the function only if there's a difference. // Standard use <p>Your selected language: {lang}</p> </> }. Again, as it We take the example from the website, and try to make it type safe. This is the second post in a series of blog posts where we are building our own super simple form component in React and TypeScript. In the last post we created our project. In this post we are going to implement very basic Form and Field components. We’ll use the render props pattern so that any content can be injected into the form. We’ll

With this even the example from docs doesn't work with Typescript as the EventTarget of A flexible and beautiful Select Input control for ReactJS with multiselect, autocomplete and ajax support. May 26 Then the code could be typesafe. Another common use of an inline function is to pass in a button’s value as an argument. This is also very common when using input elements and the onChange event handler. Take a look at the example below. Notice the value e that’s returned from the onClick event handler:

To capture when the user selects an option, add the onChange prop: <Select options={scaryAnimals} onChange={opt => console.log(opt.label, opt.value)} /> The value passed to the onChange function is the same object that makes up the option itself, so it will contain the value and label variables.

Comments
  • what does it mean typesafe ?
  • I guess it means compiled by typescript and check that all variables assignement are allright from their type. We are talking about typescript, of course, not javascript
  • As of Dec. 2016 one has to use event.currentTarget.value to get the data from the form.
  • Dave, consider updating your example.
  • @MartinMajewski I have edited to use currentTarget (joequery.me/code/event-target-vs-event-currenttarget-30-seconds is a good explanation)
  • this should be the top asnwer, FormEvent always shows error if I access e.target.value
  • I suppose that is better than casting to any, but you are still using type assertion, and that is what I was trying to avoid.
  • Yes, but since you are entirely certain that e.target is an HTMLSelectElement, this type-assertion is safe, and all subsequent type-checking is inherently safe as well, such as target.value. If you want to make it absolutely bulletproof, you could do a runtime check for its type as well, and throw a TypeError if e.target is not of the correct type. This will never actually happen, but it adds an additional layer of guaranteed type-safety.
  • stackoverflow.com/questions/260626/what-is-type-safe what I understand by typesafe is that the type checking is imposed by the compiler. That means no type assertions and not depending on runtime exceptions.
  • I previously commented that the event handler should be public, not private. I have since realized that was incorrect. Even if we had private methods at run-time (which hopefully we will in the future), a private method would still work fine here, because React doesn't need to call the private method directly but only the arrow function you're passing as the onChange prop.
  • I was hoping to get rid of the "as any" cast completely.
  • Thanks for your thoughts, but that still doesn't answer my question. I think the answer is that the .d.ts of react would need to be modified so that the signature of the onChange of a SELECT element used a new SelectFormEvent. Otherwise as you point out it needs a cast. I guess I could encapsulate that in a MYSELECT tag.
  • Okay, don't forget to answer and accept your answer :) Self answer
  • A better way of adding EventTarget.value is to augment the global eventTarget, which can be done via any .ts file: declare global { interface EventTarget { value: any; }}