在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} />
这段代码工作,但我的问题是,我不明白如何定义事件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.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>