Reputation: 2809
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);
Upvotes: 31
Views: 40936
Reputation: 9531
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';
Upvotes: 37
Reputation: 748
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.
Upvotes: 50
Reputation: 2809
You won't belive it: It was enough to move constructor assigment to render function:
render()
{
return (
<button onClick={ this.Button_Click.bind(this) }>Toggle</button>
)}
Then MouseEvent
become avaliable:
private Button_Click(event: MouseEvent): void
Why this is happening?
Upvotes: 5