【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
を指定する。