1. ホーム
  2. reactjs

[解決済み] TypescriptとReact.KonvaでonClickイベントの種類を指定する

2023-01-27 15:50:07

質問

tslintのエラーを解消したいのですが。 Type declaration of 'any' loses type-safety. を削除したいのですが、Eventの正しい型が何なのかがわからず困っています。

私はLynda "で作業しています。 フルスタックReactアプリケーションの構築とデプロイ "をTypescriptに変換しようとしているところです。

以下は、問題を引き起こしている具体的な行です。

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

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

これが私の完全な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"
  },

I を考える はKonva Layerクラスによってインデックスが追加されていると思いますが、私はreactエコシステム全体についてかなり新しいので、まだそれをすべて包み込もうとしているところです。

UPDATEです。

Tyler 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)
    }}
  />
)

どのように解決するのですか?

上記の更新で投稿したように、潜在的な解決策は @Tyler-sebastion が提案したように Declaration Merging を使用することでしょう。私は、2 つの追加のインターフェイスを定義し、index プロパティを EventTarget にインデックス プロパティを追加することができました。

interface KonvaTextEventTarget extends EventTarget {
  index: number
}

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

次に、イベントを KonvaMouseEvent として宣言します。

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

tslintエラーを克服するためだけに、ちょっとKludgyで過度に冗長な感じがするので、これが最善の方法であるかどうかはまだ100%ではありません。