reactjs 在使用MaterialUI和Typescript的React中,传递给onKeyPressed函数的事件的正确类型是什么?

jdgnovmf  于 2023-06-05  发布在  React
关注(0)|答案(1)|浏览(152)

在一个React应用程序中,我使用Typescript和MaterialUI,我有一个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 prop上时,我知道我应该使用KeyboardEvent<HTMLDivElement>,但问题是,然后我得到一个错误,显示为Type 'KeyboardEvent' is not generic
我做错了什么?
顺便说一下,如果我给予事件类型e: { key: string; target: any },一切都很好,但当我试图遵循正确的方式时,理解我做错了什么仍然很有趣。

更新

经过进一步的研究,似乎传递给keyPressed函数的事件是KeyboardEvent类型,其target属性是EventTarget类型。
查看React包中global.d.tsEventTarget的定义,然后我看到它是空接口。
global.d.ts的评论中,我还读到“警告:所有这些接口都是空的。如果你想要各种属性的类型定义(如HTMLInputElement.prototype.value),你需要添加--lib DOM(通过命令行或tsconfig.json)。但是我的tsconfig.json实际上在库中包含DOM(属性是"lib": ["dom", "dom.iterable", "esnext"],)。
同样,我可以使事情正常工作,但我想了解如何为该事件获取干净的类型。

nmpmafwu

nmpmafwu1#

您可以定义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”上不存在属性“value”。
关于此错误的另一篇文章:Property 'value' does not exist on type EventTarget in TypeScript
...当您访问value -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<HTMLInputElement>

相关问题