reactjs - Hur man använder 2 typer av händelser i TypeScript-gränssnitt
Jag behöver skapa en anpassad REST-hook som har parametern Event, och denna parameter ska kunna ta emot 2 typer av händelser - tangentbord och mus. Jag försökte använda en union av typer som MouseEvent | KeyboardEvent och det fungerar inte :/
Några förslag? Exempel nedan
<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>
const getUserPosition = (
e: MouseEvent & KeyboardEvent, <-- here is problem
queryuery: string,
assetType: AssetType
) => {
if (e?.key === 'Enter') {
// do something
}
if (e?.type === 'click') {
//do something
}
}
Svar #1
Detta är verkligen ett irriterande och konstigt drag från TypeScript. Först måste du använda typen MouseEvent | KeyboardEvent för händelsen eftersom den kommer från en onClick-callback ELLER en onKeyDown-callback.
Efter det måste du vara säker på vilken typ av händelse det är genom att kontrollera förekomsten av e.key till exempel
const getUserPosition = (e: MouseEvent | KeyboardEvent) => {
if (e.key) {
// it's a KeyboardEvent
if (e.key === "Enter") {
// do something
}
} else {
// it's a MouseEvent
if (e.type === "click") {
//do something
}
}
};
Problemet då är att du fick detta fel:
Egenskapen 'key' finns inte på typen 'MouseEvent'
Du måste använda en giltig kontroll för att vara säker på att denna egenskap key finns i objektet e. Du kan använda för detta "key" in e:
const getUserPosition = (e: MouseEvent | KeyboardEvent) => {
if ("key" in e) {
// it's a KeyboardEvent
if (e.key === "Enter") {
// do something
}
} else {
// it's a MouseEvent
if (e.type === "click") {
//do something
}
}
};
Svar #2
låt oss först titta på vad du har på funktionsdefinitionen...:
så du vill analysera en av två typer av händelser där en egenskap kan finnas på den ena men inte på den andra, så låt oss titta på detta första tillvägagångssätt...
/*
* 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
}
};
