【TypeScript】Event.targetに型を付けてvalueを参照する
困ったこと
const handleInput = (event: InputEvent) => { console.log(event.target.value); // => Property 'value' does not exist on type 'EventTarget'.};
TypeScriptでInputEvent
を扱う際などに、event.target
(event.currentTarget
)のvalue
を参照しようとすると上記のエラーになる。
原因はevent.target
が何のElement
に該当するかはコンパイラーが推論できておらず、単純にEventTarget
と推論されているため。
解決法
1. targetに型指定しつつ直接取り出す
const handleInput = (event: InputEvent) => {const handleInput = ({ target }: { target: HTMLInputElement }) => { console.log(target.value);};
target
のみを参照する場合に限る。
2. instanceofで型ガードする
const handleInput = (event: InputEvent) => { if (!(event.target instanceof HTMLInputElement)) throw new TypeError(); console.log(event.target.value);};
3. Event型を拡張する
interface HTMLElementEvent<T extends EventTarget> extends Event { target: T;}
const handleInput = (event: InputEvent) => {const handleInput = (event: HTMLElementEvent<HTMLInputElement>) => { console.log(event.target.value);};
Event
を継承した型を作成し、target
をジェネリクスで受け取った型に上書きする。
4. asで型アサーションする
const handleInput = (event: InputEvent) => { console.log(event.target.value); console.log((event.target as HTMLInputElement).value);};
これは最終手段。
Reactの場合
import type { ChangeEvent } from "react";
const handleInput = (event: InputEvent) => {const handleInput = (event: ChangeEvent<HTMLInputElement>) => { console.log(event.target.value);};
React.ChangeEvent
のジェネリクスに対象のElement
を指定する。
参考