LoginSignup
3
0

More than 3 years have passed since last update.

EventTargetのつまずき。

Last updated at Posted at 2020-12-26

今日の当番:TypeScript超初心者のちむ

ついさっきEventTargetでつまずきました。
例えばこんなコード。

main.ts
// 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にキャストするのだ

完璧。天才。そう思っていました。

main.ts
// 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つのエラーで私は成長しました。

main.ts
// 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さんと三位一体で頑張ります。

3
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
0