31

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);
6
  • Could you please show us the code where you binding this handler to element? I think there could be a root cause of this problem Commented Oct 2, 2017 at 12:02
  • You mean binding in render and constructor? Added in edit #1 Commented Oct 2, 2017 at 12:14
  • Did you try (event: React.MouseEvent<HTMLButtonElement>)? Commented Oct 2, 2017 at 12:20
  • Yes, same efect. It seems other people don't have such problems: bennadel.com/blog/… Commented Oct 2, 2017 at 12:28
  • private ButtonClickHandler(event: React.MouseEvent<HtmlButtonElement>): void should work Commented Oct 3, 2017 at 3:28

3 Answers 3

50

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.

Sign up to request clarification or add additional context in comments.

2 Comments

thanks helped me too. it seems a shame such basic issues are failing for typescript out of the box with react. adding an onClick event requires this much google fu to get it to work.
You may use React.MouseEvent<Element> to be more open.
37

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';

Comments

5

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?

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.