Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[lib.dom.d.ts] Include well-known KeyboardEvent.key values #38886

Open
5 tasks done
dimitropoulos opened this issue Jun 1, 2020 · 8 comments
Open
5 tasks done

[lib.dom.d.ts] Include well-known KeyboardEvent.key values #38886

dimitropoulos opened this issue Jun 1, 2020 · 8 comments
Labels
Experience Enhancement Noncontroversial enhancements Suggestion An idea for TypeScript
Milestone

Comments

@dimitropoulos
Copy link

dimitropoulos commented Jun 1, 2020

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.
@IllusionMH
Copy link
Contributor

IllusionMH commented Jun 1, 2020

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

@ferdaber
Copy link

ferdaber commented Jun 1, 2020

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

@dimitropoulos
Copy link
Author

dimitropoulos commented Jun 1, 2020

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.

With (works well):
Screenshot_20200601_180612

Without (doesn't work):
Screenshot_20200601_180657

@papb
Copy link

papb commented Jun 1, 2020

The LiteralUnion type was created in type-fest for this purpose. Maybe it can be used while #29729 is not solved.

@dimitropoulos
Copy link
Author

dimitropoulos commented Jun 2, 2020

Screenshot_20200602_082342

For whatever it's worth I can confirm that LiteralUnion works in this use-case (notice that '' is not an error, whereas before it was an error; also notice that the autocomplete works).

@dimitropoulos
Copy link
Author

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.

@RyanCavanaugh
Copy link
Member

RyanCavanaugh commented Jun 15, 2020

I think this is blocked on #29729 getting solved but could proceed after that

@Moh-Snoussi
Copy link

Moh-Snoussi commented Nov 19, 2021

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Experience Enhancement Noncontroversial enhancements Suggestion An idea for TypeScript
Projects
None yet
Development

No branches or pull requests

6 participants