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