何が起きたのか?
以下のコードを書きました。
// index.tsx
window.addEventListener("keydown", handleKeyDown); <== @ココ!
function handleKeyDown(event: KeyboardEvent) {
if (event.code === arrowKeys.left.keyCode) {
// なにかのコード
}
}
”@ココ!” の行の、handleKeyDown
に対して、TypeScript が次の問題を指摘しました。
No overload matches this call.
Overload 1 of 2, '(type: "keydown", listener: (this: Window, ev: KeyboardEvent) => any, options?: boolean | AddEventListenerOptions | undefined): void', gave the following error.
Argument of type '(event: KeyboardEvent<Element>) => void' is not assignable to parameter of type '(this: Window, ev: KeyboardEvent) => any'.
Types of parameters 'event' and 'ev' are incompatible.
Type 'KeyboardEvent' is missing the following properties from type 'KeyboardEvent<Element>': locale, nativeEvent, isDefaultPrevented, isPropagationStopped, persist
Overload 2 of 2, '(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions | undefined): void', gave the following error.
Argument of type '(event: KeyboardEvent<Element>) => void' is not assignable to parameter of type 'EventListenerOrEventListenerObject'.
Type '(event: KeyboardEvent<Element>) => void' is not assignable to type 'EventListener'.
Types of parameters 'event' and 'evt' are incompatible.
Type 'Event' is missing the following properties from type 'KeyboardEvent<Element>': altKey, charCode, ctrlKey, code, and 15 more.
ただ、実際の動作は問題なく、こちらが期待した通りでした。
しかし、問題ないとは言っても、いちいち指摘されると気になります。どこを直せばいいのでしょう?
エラーの解決方法
結論として、コードを以下のように書き換えました。
function handleKeyDown(event: KeyboardEvent) {
function handleKeyDown(event: globalThis.KeyboardEvent) {
event
の型定義を厳密にしろということですね。
TypeScriptも納得してくれたみたいで、エラーは表示されなくなりました。
globalThis
とは?
*GPT-3.5
The
globalThis
is a built-in global variable in JavaScript that provides a reference to the global object in any environment (including browsers and Node.js). It was introduced in ECMAScript 2020 to provide a consistent way of accessing the global object, regardless of the runtime environment.
globalThis は JavaScript の組み込みグローバル変数で、あらゆる環境(ブラウザや Node.js を含む)でグローバルオブジェクトへの参照を提供します。これは、実行環境に関係なくグローバルオブジェクトにアクセスする一貫した方法を提供するために ECMAScript 2020 で導入されました。
globalThis
が必要なことにどのようにして気づいたか?
addEventListener
内で関数を直接書きます。
window.addEventListener("keypress",(e)=>{console.log(e.type)})
VSCodeであれば、e
の部分にカーソルを合わせると、次のメッセージが現れるかと思います。
(parameter) e: globalThis.KeyboardEvent
画像だとこんなかんじ
これで必要な型がglobalThis.KeyboardEvent
であることがわかります。
以上です。