Типизация событий
Тема дорожной карты · React
Типизация событий в React с TypeScript означает аннотирование параметров обработчиков событий конкретным подтипом SyntheticEvent, соответствующим DOM-элементу и типу обрабатываемого события, — что обеспечивает полную типобезопасность для event.target, event.currentTarget и специфических для события свойств. Пакет @types/react экспортирует обобщённые типы событий: React.ChangeEvent<HTMLInputElement>, React.MouseEvent<HTMLButtonElement>, React.KeyboardEvent<HTMLTextAreaElement>, — где параметр типа указывает HTML-элемент, давая TypeScript точное знание свойств элемента. Для обработчиков отправки форм правильным типом является React.FormEvent<HTMLFormElement>, предоставляющий доступ к event.preventDefault() и свойствам элемента формы. Типизация событий в React особенно важна при создании переиспользуемых библиотек компонентов или дизайн-систем, поскольку она принуждает к явным контрактам о том, как коллбэки событий распространяются по дереву компонентов и предотвращает случайную передачу потребителями несовместимых функций-обработчиков. Распространённый паттерн в TypeScript React-проектах — определение типов обработчиков через React.EventHandler<E> или встроенные типы функций — onClick: (event: React.MouseEvent<HTMLButtonElement>) => void — в интерфейсах Props компонентов для чёткого документирования ожидаемого контекста события.
Как это работает
Типизация событий типизирует props, state, refs и события компонентов. Function-компоненты типизируются как function C(props: Props): JSX.Element или const C: React.FC<Props> (последнее спорно — теперь предпочитают явный return type). Типы событий — из namespace React: React.MouseEvent<HTMLButtonElement>, React.ChangeEvent<HTMLInputElement>. Generics делают компоненты переиспользуемыми между типами: function Select<T>(props: {items: T[], onChange: (item: T) => void}). Utility-типы (Partial, Pick, Omit, Required) производят выводные типы props из существующих.
Когда применять
Добавляйте TypeScript в любой новый React-проект >~500 строк или с >1 автором — фрикция минимальна, безопасность огромна. Типизируйте props явно (interface Props {...}); избегайте any и as-кастов (escape hatches, скрывают баги). Generics — для переиспользуемых list/select/form-компонентов. Опирайтесь на strict mode/strictNullChecks — они ловят тихие undefined-баги, которые скрывает чистый JavaScript.
Типичные ошибки
Ловушки Типизация событий: any повсюду, потому что типизировать было сложно (теряете смысл — чините или используйте unknown); as Type-касты, лгущие компилятору; не сужающийся ReactNode (рендерится всё, включая случайные boolean); борьба с inference у useState для nullable значений (useState<User|null>(null) — явно); сверхсложные generic-constraints в shared-компонентах. Когда типы больно — больно и дизайну: рефакторите, не кастуйте.