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);
Events supported are: AnimationEvent , ChangeEvent , ClipboardEvent , CompositionEvent , DragEvent , FocusEvent , FormEvent , KeyboardEvent , MouseEvent , PointerEvent , TouchEvent , TransitionEvent , WheelEvent .
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()" .
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.
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';
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With