Typescript 和 React,React.KeyboardEvent<HTMLInputElement> 编译时和运行时之间的不同类型

Lom*_*baX 3 type-inference typescript reactjs

TL;DRObject.getPrototypeOf(e.target)返回HTMLInputElement,但编译器说该类型是EventTarget

Long:我有一个简单的输入

      <input
        className="FilterInput"
        type="text"
        placeholder="Search for names..."
        onKeyUp={filter}
      />
Run Code Online (Sandbox Code Playgroud)

以及管理过滤器的功能

    const filter = (e: React.KeyboardEvent<HTMLInputElement>) => {
        console.log(Object.getPrototypeOf(e.target)) // prints "HTMLInputElement"
        console.log((e.target as HTMLInputElement).value);
        // ... other code
    }
Run Code Online (Sandbox Code Playgroud)

我试图更好地理解 Typescript 类型管理背后的理论,但是我不明白为什么我必须输入提示

(e.target as HTMLInputElement).value

在第二console.log

如果我不这样做,编译器(编译时)会说Property 'value' does not exist on type 'EventTarget'.。所以这意味着在编译时的类型e.target是EventTarget。

但是,在运行时使用 进行测试时Object.getPrototypeOf(e.target),类型为HTMLInputElement(具有该value属性)。

为什么会发生这种情况?这是我的代码中的错误吗?是与 React 有关的错误,还是我缺少的 Typescript 类型管理理论的某些部分?

此外,参数声明中的泛型类型指示(例如:React.KeyboardEvent< HTMLInputElement >)难道还不够吗?

谢谢

Avi*_*dad 5

这个问题的答案实际上与 JS 和 DOM api 更相关,而不是与 Typescript 相关。

简而言之,您真正想要的是event.currentTarget,因为它将是您附加侦听器的实际元素。

event.target可以是您元素的任何子元素。由于它可以是任何元素 - 它不能安全键入,因此它被键入为最低公分母,即EventTarget. (但我会说我不确定为什么它是 EventTarget 而不是Element

有关更多信息,请参阅此答案:What is the certain Difference between currentTarget property and target property in JavaScript