Spécifier le type d'événement onClick avec Typescript et React.Konva

j'essaie de me débarrasser de mon erreur tslint Type declaration of 'any' loses type-safety. mais j'ai du mal à trouver le bon type pour L'événement.

je suis en train de travailler à travers les Lynda "construire et déployer une application React Full-Stack " tout en essayant de le convertir à la typographie.

Voici les lignes spécifiques qui causent le problème:

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

j'ai essayé de déclarer l'événement que peu de types différents, comme React.MouseEvent<HTMLElement>, plus quelques autres sous-Types sur HTMLElement, sans succès en tant que cible.l'indice n'est pas une propriété sur n'importe quel type, je peux venir avec. Je vois d'après l'inspecteur que la cible actuelle est Konva.Le texte et l'indice est fixée à 0 mais pas sûr que ça m'aide car je ne peux pas définir le type Konva.Text, ce qui aurait du sens pour moi, mais ça ne marche pas non plus.

React Konva Event target Index

Voici mon composant fonctionnel à réaction complet:

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

Voici mon package.json dépendances:

  "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 penser L'index est ajouté par la classe de la couche Konva mais je suis assez nouveau dans l'ensemble de l'écosystème react donc j'essaie toujours d'enrouler mon cerveau autour de tout ça.

mise à jour:

J'ai pu utiliser la suggestion de Tyler Sebastion de fusionner la déclaration pour définir l'index sur la cible qui a réduit tslint au silence. Je ne suis pas sûr que ce soit la meilleure approche cependant car il se sent un peu fragile pour moi.

Voici le code d'interface supplémentaire et l'événement onclick mis à jour:

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)
    }}
  />
)
20
demandé sur Justin Levi Winter 2017-07-13 22:55:16

3 réponses

Vous n'avez probablement pas de chance sans quelques solutions de fortune

Vous pouvez essayer

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

Je ne suis pas sûr à quel point votre linter est strict - qui pourrait le fermer juste un peu

j'ai joué un peu avec elle pour un peu, et ne pouvait pas le comprendre, mais vous pouvez aussi regarder dans l'écriture de votre propre augmentée définitions: https://www.typescriptlang.org/docs/handbook/declaration-merging.html

edit: merci d'utiliser la mise en œuvre de répondre c'est la bonne façon de résoudre ce problème (et aussi upvote lui, pendant que vous y êtes).

16
répondu Tyler Sebastian 2018-07-27 16:14:38

comme indiqué dans ma mise à jour ci-dessus, une solution possible serait d'utiliser la fusion de déclaration comme suggéré par @Tyler-sebastion. J'ai pu définir deux interfaces supplémentaires et ajouter la propriété index sur le EventTarget de cette façon.

interface KonvaTextEventTarget extends EventTarget {
  index: number
}

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

je peux déclarer l'événement KonvaMouseEvent dans ma fonction onclick MouseEventHandler.

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

Je ne suis toujours pas à 100% Si c'est la meilleure approche car il se sent un peu Kludgy et trop verbeux juste pour passer l'erreur tslint.

6
répondu Justin Levi Winter 2017-07-14 15:37:05

Réagir.MouseEvent travaille pour moi:

private onClick = (e: React.MouseEvent<HTMLInputElement>) => {
  let button = e.target as HTMLInputElement;
}
2
répondu Asimov 2018-03-15 21:23:27