ElementやEventに型をつけよう
目次
はじめに
any使っていませんか?
idが"xxx"のinput要素に入力された値を取得してみてください。
この要件を w3schools のサンプルコードをコピペして実装しようとすると、
document.getElementById("xxx").value
型エラー起きてるやんけ、、😢
対象読者
- 上のような問題にお悩みの方
- TypeScript 4.4
今回の目標
DOM操作で型をつけることを目標にします。
Elementについて
DOM, Node, Elementについてそれぞれの違いを説明できますか?
最近上げた記事があるので、そちらを参考にしてください。
↓↓↓
https://zenn.dev/sqer/articles/2d4def0f07bf04c5cc47
Elementといってもその中にはHTMLElementやHTMLInputElementといったものがあります。
それぞれでオブジェクト構造も違いますので、要素によって違いを把握する必要がありそうです。
型 | 対応するタグ | 行える処理 |
---|---|---|
Element | HTMLElement |
|
HTMLElement | HTMLInputElement |
|
HTMLInputElement | Node |
Eventについて
実践!TypeScriptで型付けする
ではここから、具体的に型を付けていくにはどうすればいいのか解説していきます。
typed-query-selectorを使う
https://github.com/g-plane/typed-query-selector
querySelector
を利用する場合はもっとも強力な方法でしょう。
TypeScript4.1の機能である Template Literal Types を利用してquerySelector
の型推論を自動で行ってくれるからです。
以下が実際の実行例です。
document.querySelector('div#app') // ==> HTMLDivElement
document.querySelector('div#app > form#login') // ==> HTMLFormElement
document.querySelectorAll('span.badge') // ==> NodeListOf<HTMLSpanElement>
anElement.querySelector('button#submit') // ==> HTMLButtonElement
yarn add -D typed-query-selector
にてインストールしたあと、tsconfig.json
に以下を追加します
{
"compilerOptions": {
"types": ["typed-query-selector"] // "typed-query-selector/strict" がオススメ
}
}
Chrome拡張のように querySelector
を一度でも使うプロジェクトには入れるようにしています。
target.valueに型をつける
@types/react
にあるイベント定義を利用します
type EventHandler<E extends SyntheticEvent<any>> = { bivarianceHack(event: E): void }["bivarianceHack"];
type ReactEventHandler<T = Element> = EventHandler<SyntheticEvent<T>>;
type ClipboardEventHandler<T = Element> = EventHandler<ClipboardEvent<T>>;
type CompositionEventHandler<T = Element> = EventHandler<CompositionEvent<T>>;
type DragEventHandler<T = Element> = EventHandler<DragEvent<T>>;
type FocusEventHandler<T = Element> = EventHandler<FocusEvent<T>>;
type FormEventHandler<T = Element> = EventHandler<FormEvent<T>>;
type ChangeEventHandler<T = Element> = EventHandler<ChangeEvent<T>>;
type KeyboardEventHandler<T = Element> = EventHandler<KeyboardEvent<T>>;
type MouseEventHandler<T = Element> = EventHandler<MouseEvent<T>>;
type TouchEventHandler<T = Element> = EventHandler<TouchEvent<T>>;
type PointerEventHandler<T = Element> = EventHandler<PointerEvent<T>>;
type UIEventHandler<T = Element> = EventHandler<UIEvent<T>>;
type WheelEventHandler<T = Element> = EventHandler<WheelEvent<T>>;
type AnimationEventHandler<T = Element> = EventHandler<AnimationEvent<T>>;
type TransitionEventHandler<T = Element> = EventHandler<TransitionEvent<T>>;
例えば
<input
onChange={onChangeInput}
/>
における onChangeInputは
onChangeInput: ChangeEventHandler<HTMLInputElement> = (evt: ChangeEvent<HTMLInputElement>) => void
となってます。
まとめ
ElementやEventに型をつける方法について自分の知っている限りでいくつか紹介しました。
他にも簡単な方法を知っている方がいましたら、ぜひコメントください!
今後も型に関する様々な記事を投稿していくのでよろしくおねがいします!
Discussion