这是一个事件传递给onKeyPressed函数在React与MaterialUI和Typescript正确的类型?<



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

enter被按下时,我想访问inputhtml元素值。

所以我有下面的代码
const keyPress = (e: any) => {
if (e.key === "Enter") {
console.log("Do login", e.target.value);
}
};

在返回的React树中有这个

<TextField onKeyPress={keyPress} />

这段代码工作,但我的问题是,我不明白如何定义事件e传递给函数keyPressed的正确类型。

根据什么VSCode智能感知是建议当我悬停在onKeyPress道具,我知道我应该使用KeyboardEvent<HTMLDivElement>,但问题是,然后我得到一个错误,说Type 'KeyboardEvent' is not generic

我做错了什么?

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

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

查看React包中global.d.ts中的EventTarget的定义,然后我看到它是空接口。

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

同样,我可以使事情工作,但我想了解如何为该事件获得一个干净的类型。

您可以为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会给你下面的error…

属性'value'在类型'EventTarget'上不存在。

关于这个错误的另一个帖子:Property 'value'在TypeScript中不存在EventTarget类型

…当您访问value -e.target.valuevalue存在时,您可以通过将其强制转换为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>

最新更新