概要
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等もターゲットになりえるためエラーを吐いているようです。
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
上記では青枠をparentとしてonClickイベントをアタッチし、子要素の黄枠をchildrenとしています。
event.target と event.currentTarget の違いですが、
target
はイベントを呼び出した要素を参照し、
currentTarget
はイベントハンドラーをアタッチした要素を参照するようです。
そのため target
は変化し、 currentTarget
は変化しませんでした。
参考
MDN | Event.target
[MDN | Event.currentTarget]
(https://developer.mozilla.org/ja/docs/Web/API/Event/currentTarget)
MDN | EventTarget
stack overflow | Why is Event.target not Element in Typescript?