Edited at

【TypeScript】event.target と event.currentTargetの違いについて


概要

event.target.value を取得しようとするとTypeScriptに怒られてしまったため、event.targetについて調べ直しました。

ソース例はReact + TypeScriptで書いています。


エラー例


function Example() {
const event = (event: React.KeyboardEvent<HTMLInputElement>) => {
console.log(event.target.value); // ここで怒られる
// プロパティ 'value' は型 'EventTarget' に存在しません。ts(2339)
};

return (
<div>
<input type="text" onKeyDown={event} />
</div>
);
}

EventTargetはElementだけではなく、window等もターゲットになりえるためエラーを吐いているようです。

MDN | EventTarget


Element および document、window は、最も一般的なイベントターゲットですが、他のオブジェクトもイベントターゲットになります。例えば、XMLHttpRequest、AudioNode、AudioContext 他。



解決法


解決法1


const event = (event: React.KeyboardEvent<HTMLInputElement>) => {
console.log((event.target as Element).value);
// キャストすることで無理やり Element とする
};

キャストをして、 event.target を Element型とすることで無理やりエラーを消します。

エラーは消えますが、あまりいい感じはしません。


解決法2


const event = (event: React.KeyboardEvent<HTMLInputElement>) => {
console.log(event.currentTarget.value);
// currentTargetを使用する
};

currentTargetを使用することで、エラーを消します。

しかし、currentTargetとは何でしょうか?

次はtargetとcurrentTargetの違いを見ていきます。


targetとcurrentTargetの違い

codeSandBoxに実験例を置いています。

https://codesandbox.io/s/event-target-yzz1i

event-taget.gif

上記では青枠をparentとしてonClickイベントをアタッチし、子要素の黄枠をchildrenとしています。

event.target と event.currentTarget の違いですが、

target はイベントを呼び出した要素を参照し、

currentTarget はイベントハンドラーをアタッチした要素を参照するようです。

そのため target は変化し、 currentTarget は変化しませんでした。


参考

MDN | Event.target

MDN | Event.currentTarget

MDN | EventTarget

stack overflow | Why is Event.target not Element in Typescript?