Reputation: 1679
I'm trying to get a function to handle both click and keyboard events as I'm trying to make my web app keyboard accessible. When I use the |
symbol for the type I get an error:
Property 'key' does not exist on type 'KeyboardEvent<Element> | MouseEvent<Element, MouseEvent>'.
Property 'key' does not exist on type 'MouseEvent<Element, MouseEvent>'.
My function currently:
const handleChange = (e: React.KeyboardEvent | React.MouseEvent): void => {
if (e.type !== 'mousedown' || e.key !== ' ') return;
...other stuff...
}
Can someone point me in the right direction to get this working as expected? I could just write to separate functions, but I thought that it would be nice to keep it in one.
Upvotes: 6
Views: 5997
Reputation: 246
You can use Type Assertion to do this (https://basarat.gitbook.io/typescript/type-system/type-assertion):
const handleChange = (e: React.KeyboardEvent | React.MouseEvent): void => {
if (e.type !== 'mousedown' || (e as React.KeyboardEvent).key !== ' ') return;
...other stuff...
}
Upvotes: 9
Reputation: 3140
Your function doesn't know if e
is a KeyboardEvent
or a MouseEvent
. You'll need to implement a Type Guard to let your block of code know if it is dealing with a KeyboardEvent
.
import React from 'react'
/** ChangeEvent represents either a KeyboardEvent or a MouseEvent */
type ChangeEvent = React.KeyboardEvent | React.MouseEvent
/** Type-guard to check if event is a KeyboardEvent */
const isKeyboardEvent = (e: ChangeEvent): e is React.KeyboardEvent => {
return (e as React.KeyboardEvent).getModifierState !== undefined
}
const handleChange = (e: ChangeEvent): void => {
if (isKeyboardEvent(e)) {
// Do keyboard stuff here
if (e.type !== 'mousedown' || e.key !== ' ') return;
}
}
In this case, I'm checking to see if the event has the function getModifierState
defined, as that function should only be defined for KeyboardEvent
and not for MouseEvent
.
Upvotes: 3