[lib.dom.d.ts] Include well-known KeyboardEvent.key values
dimitropoulos opened this issue · 8 comments
Search Terms
keyCode
KeyboardEvent
KeyboardEvent.key
KeyboardEvent.keyCode
Suggestion
Include KeyboardEvent.key
values in the KeyboardEvent
interface.
The current implementation is:
interface KeyboardEvent extends UIEvent {
...
readonly key: string;
...
See here for a list of some possible values.
Here is my suggestion for how this type can be usefully updated:
type ModifierKeys = "Alt" | "AltGraph" | "CapsLock" | "Control" | "Fn" | "FnLock" | "Hyper" | "Meta" | NumLock" | "ScrollLock" | "Shift" | "Super" | "Symbol" | "SymbolLock";
type WhitespaceKeys = "Enter" | "Tab" | " ";
type NavigationKeys = "ArrowDown" | "ArrowLeft" | "ArrowRight" | "ArrowUp" | "End" | "Home" | "PageDown" | "PageUp";
type FunctionKeys = "F1" | "F2" | "F3" | "F4" | "F5" | "F6" | "F7" | "F8" | "F9" | "F10" | "F11" | "F12" | "F13" | "F14" | "F15" | "F16" | "F17" | "F18" | "F19" | "F20" | "Soft1" | "Soft2" | "Soft3" | "Soft4";
type NumericKeypadKeys = "Decimal" | "Key11" | "Key12" | "Multiply" | "Add" | "Clear" | "Divide" | "Subtract" | "Separator" | "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9";
interface KeyboardEvent extends UIEvent {
...
readonly key: string | ModifierKeys | WhitespaceKeys | NavigationKeys | FunctionKeys | NumericKeypadKeys;
...
}
In the above I left out EditingKeys
, UIKeys
, DeviceKeys
, IMEKeys
, PhoneKeys
, MultimediaKeys
, AudioControlKeys
, TVControlKeys
, MediaControllerKeys
, SpeechRecognitionKeys
, DocumentKeys
, ApplicationSelectorKeys
, and BrowserControlKeys
, but we could either include them all at the start or just as necessary.
Use Cases
When a user is accessing the KeyboardEvent.key
API, a sane set of the known defaults should be available for type checking.
Examples
This will help prevent scenarios like:
if (event.key === "ArowDown") { // <- "ArrowDown" is misspelled here
Since users will get completion on common values when typing.
note: I had previously suggested implementing this in the React types, but @ferdaber suggested (and I agree) that the dom types themselves are the better place.
Checklist
My suggestion meets these guidelines:
- This wouldn't be a breaking change in existing TypeScript/JavaScript code
- This wouldn't change the runtime behavior of existing JavaScript code
- This could be implemented without emitting different JS based on the types of the expressions
- This isn't a runtime feature (e.g. library functionality, non-ECMAScript syntax with JavaScript output, etc.)
- This feature would agree with the rest of TypeScript's Design Goals.
This will help prevent scenarios like:
if (event.key === "ArowDown") { // <- "ArrowDown" is misspelled here
Unfortunately as soon as you have string
in
readonly key: string | ModifierKeys | WhitespaceKeys ...
ArowDown
is valid value and so no error will be reported.
As for suggestions see #29729
We could go the route of ‘csstypes’ and have it be an external package that augments the current type definitions, though I’m not sure it will work if the type is already the wider string
huh. I knew that ArowDown
would be a valid value but was hoping that the UX improvement of the autocomplete would be a big enough win to make this all worth it.
I was under the impression that the autocomplete would continue to work, and didn't realize that string |
would clobber it... hmph.
I'm open @ferdaber's suggestion of making an external definition, like dom-keyboardevent-key-types.d.ts
or something. If there's consensus from others (@IllusionMH), then I can move forward with making that package. It'd be nice if it lived under this repo (in the same directory as lib.dom.d.ts
), but I can live with either. We can, therefore, much more easily use LiteralUnion
from type-fest
.
I think this is blocked on #29729 getting solved but could proceed after that
The IntelliSense will help prevent many scenarios.
Even without LiteralUnion.
I created a small external package that contains the types of the KeyboardEvent.key while the current-suggestion is blocked.