web-dev-qa-db-ja.com

React Typescriptのイベントタイプ

イベントハンドラでMouseEventタイプを使用すると、React/TypeScriptアプリをビルドできません。

_private ButtonClickHandler(event: MouseEvent): void
{
    ...
}
_

私は得る:

_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>'.`
_

_MouseEvent<HTMLButtonElement>_も試しましたが、その後_error TS2315: Type 'MouseEvent' is not generic._を取得しました。

どうして?

_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"
  }
_

編集#1:

render()でのバインド:

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

constructorで:

_this.ButtonClickHandler = this.ButtonClickHandler.bind(this);
_
12
tBlabs

ここで起こっているのは、利用可能な2つの異なるタイプがあることだと思います:jsx/lib/js/js/web.jsxのMouseEvent(タイプパラメーターはありません)とReact.MouseEvent<T> from @ types/react/index.d.ts(1つの型パラメーター、T、元の要素の型があります)。 TypeScriptは 構造化タイピング を使用するため、それらは個別の型ですが、canは互換性があります。ただし、onClickハンドラーと互換性を持たせるには、Reactのバージョンを使用する必要があります。適切なタイプのTHTMLElementが機能します。または、このハンドラーをアタッチしている要素を知っています)。

そう event: MouseEventは、onClickが特殊なバージョンのイベントタイプを必要とするため失敗します。 event: MouseEvent<HTMLElement>は、型パラメーターのない間違ったMouseEvent型を参照しているため失敗します。 React.MouseEvent<HTMLElement>は、適切な型を取得し、必要なパラメーターを指定し、結果の型がonClickハンドラーと互換性があるため機能します。

23
wiml

信じられないでしょう:コンストラクターの割り当てを移動して関数をレンダリングするだけで十分でした:

render()
{
return (
<button onClick={ this.Button_Click.bind(this) }>Toggle</button>
)}

その後、MouseEventが使用可能になります。

private Button_Click(event: MouseEvent): void

なぜこれが起こっているのですか?

3
tBlabs