使用 Typescript 和 React.Konva 指定 onClick 事件类型 [英] Specifying onClick event type with Typescript and React.Konva

查看:234
本文介绍了使用 Typescript 和 React.Konva 指定 onClick 事件类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试摆脱我的 tslint 错误 'any' 的类型声明失去类型安全性. 但我正在努力弄清楚事件的正确类型是什么.

我正在通过 Lynda "

这是我完整的 React 功能组件:

export const Squares = ({单位,坐标,gameState,win,gameOver,yourTurn,ownMark,move}:SquaresProps) =>{让正方形=坐标.map((位置:数字,索引:数字)=> {让 makeMove = 移动让 mark = gameState[index] !== 'z' ?游戏状态[索引] : 假让填充 = '黑色'//当有人获胜时,您希望方块变绿if (win && win.includes(index)) {填充 = '浅绿色'}如果(游戏结束 || !yourTurn || 标记){makeMove = () =>console.log('不!')}返回 (<文本键={索引}x={位置[0]}y={位置[1]}字体大小={单位}宽度={单位}文字={标记}填充={填充}fontFamily={'Helvetica'}aligh={'中心'}onClick={(event: any) =>{makeMove(ownMark, event.target.index)}}/>)})返回 (<层>{方块}</层>)}

这是我的 package.json 依赖项:

 "依赖项": {"konva": "^1.6.3","material-ui": "^0.18.4",反应":^ 15.6.1","react-dom": "^15.6.1","react-konva": "^1.1.3",反应路由器":~3.0.0","react-tap-event-plugin": "^2.0.1",样式组件":^2.1.0"},

认为索引是由 Konva Layer 类添加的,但我对整个 React 生态系统还很陌生,所以仍然试图将我的大脑全部包围起来.

更新:

我能够使用 Tyler Sebastion 的声明合并建议来定义使 tslint 静音的目标上的索引.我不确定这是最好的方法,因为它对我来说有点脆弱.

这是额外的接口代码和更新的onclick事件:

interface KonvaTextEventTarget 扩展 EventTarget {索引号}接口 KonvaMouseEvent 扩展了 React.MouseEvent{目标:KonvaTextEventTarget}...返回 (<文本键={索引}x={位置[0]}y={位置[1]}字体大小={单位}宽度={单位}文字={标记}填充={填充}fontFamily={'Helvetica'}aligh={'中心'}onClick={(事件:KonvaMouseEvent)=>{makeMove(ownMark, event.target.index)}}/>)

解决方案

正如我在上面的更新中发布的那样,一个潜在的解决方案是使用 @Tyler-sebastion 建议的声明合并.我能够以这种方式定义两个额外的接口并在 EventTarget 上添加 index 属性.

interface KonvaTextEventTarget 扩展 EventTarget {索引号}接口 KonvaMouseEvent 扩展了 React.MouseEvent{目标:KonvaTextEventTarget}

然后我可以在我的 onclick MouseEventHandler 函数中将事件声明为 KonvaMouseEvent.

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

如果这是最好的方法,我仍然不是 100%,因为它感觉有点笨拙和过于冗长,只是为了克服 tslint 错误.

I'm trying to get rid of my tslint error Type declaration of 'any' loses type-safety. but I'm struggling to figure out what the correct type would be for the Event.

I'm working through the Lynda "Building and Deploying a Full-Stack React Application" while trying to convert it to Typescript.

Here are the specific lines that are causing the issue:

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

I have tried to declare the event as a few different types, like React.MouseEvent<HTMLElement>, plus a few other subtypes on HTMLElement, with no success as the target.index is not a property on any type I can come up with. I can see from the inspector that the currentTarget is Konva.Text and the index is set to 0 but not sure that helps me as I can't set the type to Konva.Text, which would make sense to me, but that doesn't work either.

Here is my full React functional component:

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

Here are my package.json dependencies:

  "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 think the index is being added by the Konva Layer class but I'm pretty new to the whole react ecosystem so still trying to wrap my brain around it all.

UPDATE:

I was able use declaration merging suggestion by Tyler Sebastion to define the index on the target which silenced tslint. I'm not sure this is the best approach though as it feels a bit fragile to me.

Here is the additional interface code and updated onclick event:

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

解决方案

As posted in my update above, a potential solution would be to use Declaration Merging as suggested by @Tyler-sebastion. I was able to define two additional interfaces and add the index property on the EventTarget in this way.

interface KonvaTextEventTarget extends EventTarget {
  index: number
}

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

I then can declare the event as KonvaMouseEvent in my onclick MouseEventHandler function.

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

I'm still not 100% if this is the best approach as it feels a bit Kludgy and overly verbose just to get past the tslint error.

这篇关于使用 Typescript 和 React.Konva 指定 onClick 事件类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆