【问题标题】:Which is the right type for an event passed to the onKeyPressed function in React with MaterialUI and Typescript?使用 MaterialUI 和 Typescript 在 React 中传递给 onKeyPressed 函数的事件的正确类型是什么?
【发布时间】:2021-05-30 23:08:33
【问题描述】:

在我使用 Typescript 和 MaterialUI 的 React 应用程序中,我有一个 TextField。

我想在按下enter 时访问input html 元素值。

所以我有以下代码

  const keyPress = (e: any) => {
    if (e.key === "Enter") {
      console.log("Do login", e.target.value);
    }
  };

在返回的 React 树的某个地方我有这个

<TextField onKeyPress={keyPress} />

此代码有效,但我的问题是我不明白如何为传递给函数 keyPressed 的事件 e 定义正确的类型。

根据 VSCode intellisense 在我将鼠标悬停在 onKeyPress 道具上时的建议,我知道我应该使用 KeyboardEvent&lt;HTMLDivElement&gt;,但问题是我收到一个错误,上面写着 Type 'KeyboardEvent' is not generic

我做错了什么?

顺便说一句,如果我将事件类型设为 e: { key: string; target: any },一切都会正常工作,但是当我尝试遵循正确的方式时,了解我做错了什么仍然很有趣。

更新

经过更多研究,似乎传递给keyPressed 函数的事件是KeyboardEvent 类型,它的target 属性是EventTarget 类型。

查看global.d.tsReact包中的EventTarget的定义,然后发现是空接口。

global.d.ts 的 cmets 中,我还读到“警告:所有这些接口都是空的。如果您想要各种属性的类型定义 (比如HTMLInputElement.prototype.value),你需要添加--lib DOM(通过命令行或者tsconfig.json)。但是我的tsconfig.json实际上在库中包含DOM(属性是"lib": ["dom", "dom.iterable", "esnext"],) .

同样,我可以让事情正常进行,但我想了解如何为该事件获取干净的类型。

【问题讨论】:

  • 您可以在编辑器中通过在onKeyPress 属性上执行CTRL+click 直接看到这一点,这将带您进入material-ui 的*.d.ts 文件。
  • @Ajeet Shah 感谢您的回复,但您的建议并不那么简单,至少对我而言。 onKeyPress 的类型为 KeyboardEventHandler&lt;T&gt;。如果我查看KeyboardEventHandler&lt;T&gt;,我发现它被定义为EventHandler&lt;KeyboardEvent&lt;T&gt;&gt;。然后我查看EventHandler&lt;KeyboardEvent&lt;T&gt;&gt;,它被定义为EventHandler&lt;E extends SyntheticEvent&lt;any&gt;&gt; = { bivarianceHack(event: E): void }["bivarianceHack"];。现在事情对我来说变得有点复杂了。最终结果是我无法为传递给keyPress 函数的事件提供一个干净的类型。

标签: reactjs typescript react-typescript react-material


【解决方案1】:

您可以将onKeyPress 处理程序的类型定义为:keyPress

import { KeyboardEvent, EventHandler } from 'react'

const keyPress: EventHandler<KeyboardEvent<HTMLInputElement>> = (e) => {
  if (e.key === 'Enter') {
    console.log('Do login', (e.target as HTMLInputElement).value)
  }
}

<TextField id="id" label="Name" onKeyPress={keyPress} />

Typescript 会给你以下错误...

“EventTarget”类型上不存在属性“值”。

关于这个错误的另一个帖子:Property 'value' does not exist on type EventTarget in TypeScript

...当您访问值时 - e.target.value 尽管存在 value,因此您可以通过将其转换为 HTMLInputElement 来抑制此错误,如上所示。

在我看来,您正在尝试访问e.key,而不是onKeyPress 处理程序中的e.target.value;因为您最有可能在 onChange 处理程序中这样做。


相同,但形式可能更短:

type KeyPressType<T = Element> = EventHandler<KeyboardEvent<T>>

const keyPress: KeyPressType<HTMLInputElement> = (e) => {
  if (e.key === 'Enter') {
    console.log('Do login', (e.target as HTMLInputElement).value)
  }
}

问题:e的类型是什么?

答案:KeyboardEvent&lt;HTMLInputElement&gt;

【讨论】:

    猜你喜欢
    • 2021-07-12
    • 2018-03-09
    • 2019-05-10
    • 1970-01-01
    • 2017-08-19
    • 2018-03-18
    • 2015-01-02
    • 2021-08-07
    • 1970-01-01
    相关资源
    最近更新 更多