Reactjs 如何在typescript界面中使用两种类型的事件
我需要创建一个带有参数Event的定制rest钩子,这个参数应该能够接收两种类型的事件——键盘和鼠标。我试图使用类型的联合,如Reactjs 如何在typescript界面中使用两种类型的事件,reactjs,typescript,Reactjs,Typescript,我需要创建一个带有参数Event的定制rest钩子,这个参数应该能够接收两种类型的事件——键盘和鼠标。我试图使用类型的联合,如MouseEvent | KeyboardEvent,但它不起作用:/ 有什么建议吗?下面的例子 <input type="text" value={query} onChange={e => setQuery(e.target.value)} onKeyDown={e => getUserPosition(e, qu
MouseEvent | KeyboardEvent
,但它不起作用:/
有什么建议吗?下面的例子
<input
type="text"
value={query}
onChange={e => setQuery(e.target.value)}
onKeyDown={e => getUserPosition(e, query, assetType)}
/>
<Button
fullWidth
color="secondary"
onClick={e => getUserPosition(e, query, assetType)}
>
Search
</Button>
setQuery(e.target.value)}
onKeyDown={e=>getUserPosition(e,查询,资产类型)}
/>
getUserPosition(e,查询,资产类型)}
>
搜寻
const getUserPosition=(
e:MouseeEvent和KeyboardEvent{
如果(e?.key=='Enter'){
//做点什么
}
如果(e?.type==='单击'){
//做点什么
}
}
这确实是TypeScript的一个恼人而奇怪的举动。首先,你必须使用类型MouseeEvent | KeyboardEvent
作为事件,因为它来自于一个onClickcallback或onKeyDown
回调
之后,您必须通过检查是否存在e.key
来确定这是什么类型的事件
const getUserPosition=(e:MouseEvent | KeyboardEvent)=>{
if(e.key){
//这是一个键盘事件
如果(e.key==“输入”){
//做点什么
}
}否则{
//这是一个老鼠事件
如果(例如,键入==“单击”){
//做点什么
}
}
};
然后,问题是您出现了以下错误:
类型“MouseEvent”上不存在属性“key”
您必须使用有效的检查来确保对象e
中存在此属性key
。您可以对该“key”在e
中使用:
const getUserPosition=(e:MouseEvent | KeyboardEvent)=>{
如果(e中的“键”){
//这是一个键盘事件
如果(e.key==“输入”){
//做点什么
}
}否则{
//这是一个老鼠事件
如果(例如,键入==“单击”){
//做点什么
}
}
};
让我们先看看您在函数定义上有什么…:
因此,您希望解析两种事件中的一种,其中一个属性可能存在于其中一个上,但另一个上不存在,因此让我们看看第一种方法
/*
* I Like your initial approach because it makes more logical sense this way,
* only that you have to check if the property value you want to check is actually
* in the value
*/
const getUserPosition = (e: MouseEvent | KeyboardEvent) => {
if ('key' in e && e?.key === 'Enter') {
// do something
}
if ('type' in e && e?.type === 'click') {
//do something
}
};
您可以尝试下一个解决方案。Aka策略模式
:
import React,{FC}来自“React”
键入ClickHandler=(e:React.MouseEvent)=>any
常量按钮:FC=()=>e}>
const hasProperty=(obj:T,prop:P)=>Object.prototype.hasOwnProperty.call(obj,prop);
常量isKeyboard=(e:React.KeyboardEvent | React.MouseEvent):
e是React.KeyboardEvent=>hasProperty(e,“键”)
const isMouse=(e:React.KeyboardEvent | React.MouseEvent):
e是React.KeyboardEvent=>hasProperty(e,'type')&&e.type=='click'
常量应用程序:FC=()=>{
函数getUserPosition(e:React.MouseEvent):()=>(查询:字符串)=>任意
函数getUserPosition(e:React.KeyboardEvent):()=>(查询:字符串)=>任意
函数getUserPosition(e:React.MouseEvent | React.KeyboardEvent){
返回函数(查询:字符串){
常数x=e;
如果(isKeyboard(e)&&e.key==='Enter'){
}
if(isMouse(e)){
//做点什么
}
}
}
返回(
getUserPosition(e)}
/>
getUserPosition(e)}
>
搜寻
)
}
尝试使用e:Partial
Partial
是typescript提供的一种非常有用的实用程序类型,而且还有更多…@AshwynHorton似乎函数对此没有问题,但当我想使用它时,键入是错误的:/“类型'KeyboardEvent'的参数不能分配给类型'Partial'的参数。”好的,等一下…让我试着提供一个合适的解决方案为什么你不写两个处理程序,每种类型的事件一个?这会让你的代码更容易理解,处理不同的事件类型也不是问题。或者,根本不传递事件,在你的arrow函数中提取值,并做第一个处理程序的t参数是字符串。
运算符中的有一个小错误
/*
* I Like your initial approach because it makes more logical sense this way,
* only that you have to check if the property value you want to check is actually
* in the value
*/
const getUserPosition = (e: MouseEvent | KeyboardEvent) => {
if ('key' in e && e?.key === 'Enter') {
// do something
}
if ('type' in e && e?.type === 'click') {
//do something
}
};