davestevens davestevens - 1 month ago 15
Javascript Question

typesafe select onChange event using reactjs and typescript

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

Answer

As far as I can tell, this is currently not possible - a cast is always needed.

To make it possible, 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. The new event type would expose target, which exposes value. Then the code could be typesafe.

Otherwise there will always be the need for a cast to any.

I could encapsulate all that in a MYSELECT tag.