web-dev-qa-db-ja.com

TypeScriptとReact.KonvaでonClickイベントタイプを指定する

TslintエラーType declaration of 'any' loses type-safety.を削除しようとしていますが、イベントの正しいタイプが何であるかを把握するのに苦労しています。

私は、Lynda「 フルスタックReactアプリケーションの構築とデプロイ 」を使用して、TypeScriptに変換しようとしています。

問題の原因となっている特定の行は次のとおりです。

onClick={(event: any) => {
 makeMove(ownMark, event.target.index)
}}

React.MouseEvent<HTMLElement>のようないくつかの異なるタイプに加えて、HTMLElement上のいくつかの他のサブタイプとしてイベントを宣言しようとしましたが、target.indexは思いつくタイプのプロパティではないため成功しませんでした。インスペクターからcurrentTargetがKonva.Textであり、インデックスが0に設定されていることがわかりますが、タイプをKonva.Textに設定できないので、それが助けになるのかわかりません私ですが、それでもうまくいきません。

React Konva Event target Index

これが私の完全なReact機能コンポーネントです。

export const Squares = ({units, coordinates, gameState, win, gameOver, yourTurn, ownMark, move}: SquaresProps) => {
  let squares = coordinates.map( (position: number, index: number) => { 
    let makeMove = move
    let mark = gameState[index] !== 'z' ? gameState[index] : false
    let fill = 'black'

    // when someone wins you want the square to turn green
    if (win && win.includes(index)) {
      fill = 'lightGreen'
    }

    if (gameOver || !yourTurn || mark) {
      makeMove = () => console.log('nope!')
    }

    return (
      <Text
        key={index}
        x={position[0]}
        y={position[1]}
        fontSize={units}
        width={units}
        text={mark}
        fill={fill}
        fontFamily={'Helvetica'}
        aligh={'center'}
        onClick={(event: any) => {
          makeMove(ownMark, event.target.index)
        }}
      />
    )
  })

  return (
    <Layer>
      {squares}
    </Layer>
  )
}

ここに私のpackage.json依存関係があります:

  "dependencies": {
    "konva": "^1.6.3",
    "material-ui": "^0.18.4",
    "react": "^15.6.1",
    "react-dom": "^15.6.1",
    "react-konva": "^1.1.3",
    "react-router": "~3.0.0",
    "react-tap-event-plugin": "^2.0.1",
    "styled-components": "^2.1.0"
  },

thinkインデックスはKonva Layerクラスによって追加されていますが、反応するエコシステム全体はかなり新しいので、脳をラップしようとしていますすべて。

更新:

Tliner Sebastionの提案をマージする宣言を使用して、tslintを沈黙させるターゲットのインデックスを定義することができました。これが最善のアプローチであるかどうかはわかりませんが、それは私には少しもろい感じがします。

追加のインターフェイスコードと更新されたonclickイベントは次のとおりです。

interface KonvaTextEventTarget extends EventTarget {
  index: number
}

interface KonvaMouseEvent extends React.MouseEvent<HTMLElement> {
  target: KonvaTextEventTarget
}

...

return (
  <Text
    key={index}
    x={position[0]}
    y={position[1]}
    fontSize={units}
    width={units}
    text={mark}
    fill={fill}
    fontFamily={'Helvetica'}
    aligh={'center'}
    onClick={(event: KonvaMouseEvent) => {
      makeMove(ownMark, event.target.index)
    }}
  />
)
36

上記の私の更新で投稿されたように、潜在的な解決策は、@ Tyler-sebastionが示唆する宣言マージを使用することです。この方法で、2つの追加のインターフェイスを定義し、EventTargetにインデックスプロパティを追加できました。

interface KonvaTextEventTarget extends EventTarget {
  index: number
}

interface KonvaMouseEvent extends React.MouseEvent<HTMLElement> {
  target: KonvaTextEventTarget
}

その後、onclick MouseEventHandler関数でKonvaMouseEventとしてイベントを宣言できます。

onClick={(event: KonvaMouseEvent) => {
          makeMove(ownMark, event.target.index)
}}

これが最善のアプローチである場合、私はまだ100%ではありません。tslintエラーを乗り越えるために少し気味が悪く、過度に冗長に感じます。

9

あなたはおそらくいくつかのハック-yの回避策なしで運が悪い

試すことができます

onClick={(event: React.MouseEvent<HTMLElement>) => {
 makeMove(ownMark, (event.target as any).index)
}}

私はあなたのリンターがどれほど厳しいのか分かりません-それはほんの少しそれを止めるかもしれません

私は少し試してみましたが、理解できませんでしたが、独自の拡張定義を書くこともできます: https://www.typescriptlang.org/docs/handbook/declaration-merging .html

編集: この応答 で実装を使用してくださいこの問題を解決する適切な方法です(そして彼を賛成しながらあなたはそれでいる)。

41
Tyler Sebastian

React.MouseEventは私のために働いています:

private onClick = (e: React.MouseEvent<HTMLInputElement>) => {
  let button = e.target as HTMLInputElement;
}
8
Asimov