In this code
document.addEventListener('keydown', (e: SyntheticKeyboardEvent<Document>) => {
if (e.ctrlKey && e.shiftKey && e.code === 'KeyE' && !this.state.envChangePopupOpened) {
this.openPopup();
}
});
Flow gives 2 issues which seem to not be as such.
First it gives this cryptic message:
Cannot call `document.addEventListener` because: Either string [1] is incompatible with enum [2]. Or string [1] is incompatible with enum [3]. Or `KeyboardEvent` [4] is incompatible with `SyntheticKeyboardEvent` [5] in the first argument. Or string [1] is incompatible with enum [6]. Or string [1] is incompatible with string literal `wheel` [7]. Or string [1] is incompatible with enum [8]. Or string [1] is incompatible with enum [9]. Or string [1] is incompatible with enum [10]. Or string [1] is incompatible with enum [11]. Or string [1] is incompatible with enum [12]. Or `Event` [13] is incompatible with `SyntheticKeyboardEvent` [5] in the first argument. (References: [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11] [12] [13])
and second gives:
property `code` is missing in `SyntheticKeyboardEvent` [1]. (References: [1])
But it should be on e.
How do you handle these?
EDIT:
The second issue turns out is not supported in SyntheticEvent and should be worked around.
The keydown event is fired when a key is pressed. Unlike the deprecated keypress event, the keydown event is fired for all keys, regardless of whether they produce a character value. The keydown and keyup events provide a code indicating which key is pressed, while keypress indicates which character was entered.
The simple solution: just use the keyup event (and not the keydown event). This will give you the latest value after the user typed the latest character. That resolves the issue.
5. Which of the following are not key event properties? Explanation: altKey, ctrlKeY, shiftKey, and metaKey are key event object's properties, which are set to true if the corresponding modifier key is held down when the event occurs.
An event which indicates that a keystroke occurred in a component. This low-level event is generated by a component object (such as a text field) when a key is pressed, released, or typed.
The problem is that SyntheticKeyboardEvent
is a type for events that are handled through React's event system. Because you are calling document.addEventListener
directly you will not get a synthetic event; you will get a native event instead. The type for native keyboard events is KeyboardEvent
which is defined in Flow's built-in DOM type definitions. You can change the event type like this:
document.addEventListener('keydown', (e: KeyboardEvent) => {
if (e.ctrlKey && e.shiftKey && e.code === 'KeyE' && !this.state.envChangePopupOpened) {
this.openPopup();
}
});
The KeyboardEvent
type does have a code
property.
To understand why the error message is so weird you can look at Flow's built-in definition for addEventListener
, and see that it has many overloaded signatures. The reason for this is that event objects for different event types come with different properties. (The code
and shiftKey
properties are good examples.) The overloaded signatures for addEventListener
relate specific event types to corresponding event object types. This is the overload you want to use:
addEventListener(
type: KeyboardEventTypes,
listener: KeyboardEventListener,
optionsOrUseCapture?: EventListenerOptionsOrUseCapture
): void;
This is the definition for the keyboard event types:
type KeyboardEventTypes = 'keydown' | 'keyup' | 'keypress';
Each overloaded signature uses a similar enum type for its type
parameter. You get a long, complicated error message because there is a type mismatch in one of the arguments, and Flow does not know for certain which of the many overloaded signatures of addEventListener
is the one that you want. The messages saying string is incompatible with enum
inform you that if you use a different argument for type
you will get a different signature, and as far as Flow knows maybe that could fix the problem.
Of course using a different type
argument is not the source of your problem. There is another clue in the error message, Or KeyboardEvent [4] is incompatible with SyntheticKeyboardEvent
which points you to the proper event type for the event value in your callback.
In other circumstances you could remove the type annotation from the callback argument, and let Flow infer the correct type. But because addEventListener
is overloaded Flow cannot infer the event type in this case.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With