React передає в обробники синтетичні події - обгортки над подіями браузера з однаковою поведінкою в усіх браузерах. Для кожного виду події є свій тип, параметризований елементом.
Інлайн-обробник типізувати не треба - TypeScript виведе тип сам:
<input onChange={(event) => setName(event.target.value)} />
// event: React.ChangeEvent<HTMLInputElement>
Окрема функція потребує явного типу:
import type { ChangeEvent, FormEvent, MouseEvent } from 'react';
function handleChange(event: ChangeEvent<HTMLInputElement>) {
setEmail(event.target.value);
}
function handleSubmit(event: FormEvent<HTMLFormElement>) {
event.preventDefault();
}
function handleClick(event: MouseEvent<HTMLButtonElement>) {
console.log(event.clientX);
}
Найчастіші типи: ChangeEvent, FormEvent, MouseEvent, KeyboardEvent, FocusEvent, DragEvent, ClipboardEvent.
Тип самого обробника - зручно для props:
type SearchProps = {
onSearch: (query: string) => void; // власний колбек
onKeyDown?: React.KeyboardEventHandler<HTMLInputElement>; // обробник DOM-події
};
KeyboardEventHandler<T> - це (event: KeyboardEvent<T>) => void.
Як дізнатися правильний тип: навести курсор на onChange в JSX - редактор покаже очікувану сигнатуру.
target чи currentTarget:
currentTarget- елемент, на якому висить обробник, і його тип відомий (HTMLButtonElement);target- елемент, де виникла подія (може бути вкладений<span>усередині кнопки), тому дляMouseEventвін має загальний типEventTarget.
Для полів введення event.target.value працює, бо в ChangeEvent<HTMLInputElement> тип target уточнено.
Пастки:
- власні колбеки не варто типізувати як події DOM:
onSelect: (event) => ...з передачею всього об'єкта події змушує батька знати про DOM. Краще передавати значення:onSelect(item.id); anyдля події вимикає перевірку доступу до полів - друкарська помилкаevent.target.vauleпройде непоміченою.