Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React event type in Typescript

I can't build my React/Typescript app when I use MouseEvent type in my event handler:

private ButtonClickHandler(event: MouseEvent): void {     ... } 

I get:

error TS2322: Type '{ onClick: (event: MouseEvent) => void; children: string; }' is not assignable to type 'DetailedHTMLProps<ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>'.   Type '{ onClick: (event: MouseEvent) => void; children: string; }' is not assignable to type 'ButtonHTMLAttributes<HTMLButtonElement>'.     Types of property 'onClick' are incompatible.       Type '(event: MouseEvent) => void' is not assignable to type 'EventHandler<MouseEvent<HTMLButtonElement>>'.         Types of parameters 'event' and 'event' are incompatible.           Type 'MouseEvent<HTMLButtonElement>' is not assignable to type 'MouseEvent'.             Property 'fromElement' is missing in type 'MouseEvent<HTMLButtonElement>'.` 

I also tried MouseEvent<HTMLButtonElement> but then I got error TS2315: Type 'MouseEvent' is not generic..

Why?

Excerpt from my package.json:

 "devDependencies": {     "@types/react": "^16.0.7",     "@types/react-dom": "^15.5.5",     "ts-loader": "^2.3.7",     "typescript": "^2.5.3",     "webpack": "^3.6.0"   },   "dependencies": {     "react": "^16.0.0",     "react-dom": "^16.0.0"   } 

Edit #1:

Binding in render():

<button onClick={ this.ButtonClickHandler }>Toggle</button> 

in constructor:

this.ButtonClickHandler = this.ButtonClickHandler.bind(this); 
like image 813
tBlabs Avatar asked Oct 02 '17 11:10

tBlabs


People also ask

What is type of event in React TypeScript?

Events supported are: AnimationEvent , ChangeEvent , ClipboardEvent , CompositionEvent , DragEvent , FocusEvent , FormEvent , KeyboardEvent , MouseEvent , PointerEvent , TouchEvent , TransitionEvent , WheelEvent .

What is the data type of React event?

React events are written in camelCase syntax: onClick instead of onclick . React event handlers are written inside curly braces: onClick={shoot} instead of onClick="shoot()" .


Video Answer


2 Answers

I think what's happening here is that there are two distinct types available: MouseEvent from jsx/lib/js/js/web.jsx (which has no type parameters), and React.MouseEvent<T> from @types/react/index.d.ts (which has one type parameter, T, the type of the element from which it came). Typescript uses structural typing, so even though they are distinct types, they can be compatible. But in order to be compatible with the onClick handler you need to use React's version, with an appropriate type for T (HTMLElement will work, or you can be more specific if you know what element you're attaching this handler to).

So event: MouseEvent fails because onClick requires the specialized version of the event type. event: MouseEvent<HTMLElement> fails because it refers to the wrong MouseEvent type, the one without a type parameter. React.MouseEvent<HTMLElement> works because you get the proper type, give it the parameter it needs, and the resulting type is compatible with the onClick handler.

like image 199
wiml Avatar answered Sep 24 '22 15:09

wiml


I had the same issue but was able to fix it by explicity importing the MouseEvent from React

I had the error with this

import React from 'react'; 

But fixed with this

import React, { MouseEvent } from 'react'; 
like image 43
Matt Dell Avatar answered Sep 23 '22 15:09

Matt Dell