使用 MaterialUI 和 Typescript 在 React 中传递给 onKeyPressed 函数的事件的正确类型是什么?
Which is the right type for an event passed to the onKeyPressed function in React with MaterialUI and Typescript?
在我使用 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<HTMLDivElement>
,但问题是我得到一个错误,上面写着Type 'KeyboardEvent' is not generic
.
我做错了什么?
顺便说一下,如果我给事件类型 e: { key: string; target: any }
,一切正常,但是当我尝试按照正确的方式进行时,理解我做错了什么仍然很有趣。
更新
经过更多研究,传递给 keyPressed
函数的事件似乎是 KeyboardEvent
类型,而它的 target
属性 是 [=23] 类型=].
查看React
包中global.d.ts
中EventTarget
的定义,发现是空接口
在 global.d.ts
的评论中,我还读到“警告:所有这些接口都是空的。如果你想要各种属性的类型定义
(比如HTMLInputElement.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 会给你以下错误...
Property 'value' does not exist on type 'EventTarget'.
关于此错误的另一个 post:
... 当您访问值时 - 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>
在我使用 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<HTMLDivElement>
,但问题是我得到一个错误,上面写着Type 'KeyboardEvent' is not generic
.
我做错了什么?
顺便说一下,如果我给事件类型 e: { key: string; target: any }
,一切正常,但是当我尝试按照正确的方式进行时,理解我做错了什么仍然很有趣。
更新
经过更多研究,传递给 keyPressed
函数的事件似乎是 KeyboardEvent
类型,而它的 target
属性 是 [=23] 类型=].
查看React
包中global.d.ts
中EventTarget
的定义,发现是空接口
在 global.d.ts
的评论中,我还读到“警告:所有这些接口都是空的。如果你想要各种属性的类型定义
(比如HTMLInputElement.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 会给你以下错误...
Property 'value' does not exist on type 'EventTarget'.
关于此错误的另一个 post:
... 当您访问值时 - 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>