使用reactjs和typescript的typesafe select onChange事件

我已经弄清楚了如何使用事件的丑陋转换将事件处理程序绑定到SELECT元素上。

是否可以以类型安全的方式检索值而无需强制转换为任何值?

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>
        );
    }
}
JinJinDavaid2020/03/19 14:23:29

除了@thoughtrepo的答案:

在React中没有确定类型的事件之前,为输入控件提供特殊的目标接口可能会很有用:

export interface FormControlEventTarget extends EventTarget{
    value: string;
}

然后在您的代码中将其转换为这种类型,以适合具有 IntelliSense支持的位置:

 import {FormControlEventTarget} from "your.helper.library"

 (event.target as FormControlEventTarget).value;
Pro猿A2020/03/19 14:23:29

JSX

<select value={ this.state.foo } onChange={this.handleFooChange}>
    <option value="A">A</option>
    <option value="B">B</option>
</select>

TypeScript

private handleFooChange = (event: React.FormEvent<HTMLSelectElement>) => {
    const element = event.target as HTMLSelectElement;
    this.setState({ foo: element.value });
}
飞云小小猪猪2020/03/19 14:23:29

据我所知,这目前是不可能的-始终需要强制转换。

为了使其成为可能,需要修改react的.d.ts,以便SELECT元素的onChange的签名使用新的SelectFormEvent。新的事件类型将公开目标,该目标公开值。然后,代码可以是类型安全的。

否则,总是需要对任何对象进行强制转换。

我可以将所有内容封装在MYSELECT标记中。

老丝路易2020/03/19 14:23:29

有用:

type HtmlEvent = React.ChangeEvent<HTMLSelectElement>

const onChange: React.EventHandler<HtmlEvent> = 
   (event: HtmlEvent) => { 
       console.log(event.target.value) 
   }
神乐西门2020/03/19 14:23:28

最简单的方法是将类型添加到接收值的变量中,如下所示:

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

或者,您也可以像这样投射value属性event.target

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

编辑:

最后,您可以定义EventTarget.value单独.d.ts文件中的内容。但是,该类型必须与其他地方使用的类型兼容,并且any无论如何您最终都会再次使用

全球公司

interface EventTarget {
    value: any;
}