今日の当番:TypeScript超初心者のちむ
ついさっきEventTargetでつまずきました。
例えばこんなコード。
// aタグをクリックしたときに発火させたい関数
const func = (e: Event) => {
const target = e.target.hash;
// 以下略・・・
};
ここで.hash
にこんなエラーがでます。
Property 'hash' does not exist on type 'EventTarget'.
EventTargetにはhash
というプロパティがないんだって。
え〜なんだって!
でもevent.taeget
で取得できるのって、HTMLElementでは??
コンソールで出力するとHTMLElementが取得されてるんだもん。おかしいじゃん??
私の勘違い①:event.targetの型はHTMLElementでしょ!
と思ってました。全くもって違いました。おばかですね。
エラー文に書いてある通り「EventTarget」という型です。
落ち着いて、いったんEventTagetの型定義を見てみる。(英語やら説明やらは省く)
/** EventTarget is a DOM interface implemented by objects that can receive events and may have listeners for them. */
interface EventTarget {
addEventListener(type: string, listener: EventListenerOrEventListenerObject | null, options?: boolean | AddEventListenerOptions): void;
dispatchEvent(event: Event): boolean;
removeEventListener(type: string, callback: EventListenerOrEventListenerObject | null, options?: EventListenerOptions | boolean): void;
}
ええ、確かにhash
なんてありませんね。
しかも、EventTarget
に入るのはHTMLElementだけでは無いようです。
Element および document、window は、最も一般的なイベントターゲットですが、他のオブジェクトもイベントターゲットになります。例えば、XMLHttpRequest、AudioNode、AudioContext 他。
(MDN参照:https://developer.mozilla.org/ja/docs/Web/API/EventTarget)
へえなるほどね。完全に理解した。
そして訪れる2つめの勘違い。
私の勘違い②:じゃあHTMLElementにキャストするのだ
完璧。天才。そう思っていました。
// aタグをクリックしたときに発火させたい関数
const func = (e: Event) => {
const target = e.target as HTMLElement;
const hash = target.hash;
// 以下略・・・
};
・・・いや.hash
にエラー出たままなんだけど?
エラー文もほぼ同じ
Property 'hash' does not exist on type 'HTMLElement'.
まさか・・・!そう思い覗いたHTMLElementのプロパティ。
もちろんhash
なんて存在しない。ぴえん。浅はか。
https://developer.mozilla.org/ja/docs/Web/API/HTMLElement
勝手に思いこむ前にちゃんと確認しましょう。
でも惜しかったね!よく頑張ったね!
aタグしか入ってこないんだから、HTMLAnchorElementでキャストしてあげようね!
そしてたどり着いたゴール
おめでとう。この1つのエラーで私は成長しました。
// aタグをクリックしたときに発火させたい関数
const func = (e: Event) => {
const target = e.target as HTMLAnchorElement;
const hash = target.hash;
// 以下略・・・
};
ちなみに、hash
というプロパティはHTMLHyperlinkElementUtilsに含まれているのですが、
実験的な機能のため対応していないブラウザもあります。(IEとか、あとはIEとか)
使う際には注意が必要です。polyfill入れたら良いのかも?
(↓詳しくはこちら)
https://developer.mozilla.org/ja/docs/Web/API/HTMLHyperlinkElementUtils
こうして私は強くなる
浅はか人間に厳しいTypeScriptさん。でもちゃんとエラーで教えてくれる心強いTypeScriptさん。
メゲナイ!しょげない!泣いちゃダメ!
MDNさんとTypeScriptさんと三位一体で頑張ります。