Jus*_*ter 44 typescript reactjs konvajs
我试图摆脱我的tslint错误,Type declaration of 'any' loses type-safety.但我正在努力弄清楚事件的正确类型.
我正在尝试将Lynda" 构建和部署全栈反应应用程序 ",同时尝试将其转换为Typescript.
以下是导致此问题的具体行:
onClick={(event: any) => {
makeMove(ownMark, event.target.index)
}}
Run Code Online (Sandbox Code Playgroud)
我试图将事件声明为几种不同的类型,例如React.MouseEvent<HTMLElement>,加上HTMLElement上的一些其他子类型,但没有成功,因为target.index不是我能提出的任何类型的属性.我可以从检查器看到currentTarget是Konva.Text并且索引设置为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>
)
}
Run Code Online (Sandbox Code Playgroud)
这是我的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"
},
Run Code Online (Sandbox Code Playgroud)
我认为索引是由Konva Layer类添加的,但我对整个反应生态系统都很陌生,所以仍然试图将我的大脑包裹起来.
我能够使用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)
}}
/>
)
Run Code Online (Sandbox Code Playgroud)
Tyl*_*ian 48
如果没有一些黑客的解决方法,你可能会运气不好
你可以试试
onClick={(event: React.MouseEvent<HTMLElement>) => {
makeMove(ownMark, (event.target as any).index)
}}
Run Code Online (Sandbox Code Playgroud)
我不确定你的短信有多严格 - 这可能会让它稍微关闭一下
我玩了一会儿,无法弄清楚,但你也可以考虑编写自己的增强定义:https://www.typescriptlang.org/docs/handbook/declaration-merging.html
编辑:请使用这个回复中的实现,这是解决这个问题的正确方法(并且当你在它时也支持他).
小智 17
你可以这样做
onClick: React.MouseEventHandler<HtmlInputElement> = (e) => {
const button = e.target as HTML
}
Run Code Online (Sandbox Code Playgroud)
Jus*_*ter 11
正如我在上面的更新中所发布的,可能的解决方案是使用@ Tyler-sebastion建议的声明合并.我能够定义两个额外的接口,并EventTarget以这种方式添加索引属性.
interface KonvaTextEventTarget extends EventTarget {
index: number
}
interface KonvaMouseEvent extends React.MouseEvent<HTMLElement> {
target: KonvaTextEventTarget
}
Run Code Online (Sandbox Code Playgroud)
然后,我可以KonvaMouseEvent在我的onclick MouseEventHandler函数中声明该事件.
onClick={(event: KonvaMouseEvent) => {
makeMove(ownMark, event.target.index)
}}
Run Code Online (Sandbox Code Playgroud)
如果这是最好的方法,我仍然不是100%,因为它感觉有点Kludgy并且过于冗长只是为了克服tslint错误.
小智 11
我认为正确的类型是
event:React.MouseEvent<HTMLButtonElement, MouseEvent>
Run Code Online (Sandbox Code Playgroud)
Asi*_*mov 10
React.MouseEvent适合我:
private onClick = (e: React.MouseEvent<HTMLInputElement>) => {
let button = e.target as HTMLInputElement;
}
Run Code Online (Sandbox Code Playgroud)
您应该使用 event.currentTarget。React 反映了 currentTarget(事件附加到的元素)和 target(事件当前发生的元素)之间的差异。由于这是一个鼠标事件,因此两者在类型上可能不同,即使单击没有意义。
https://github.com/facebook/react/issues/5733 https://developer.mozilla.org/en-US/docs/Web/API/Event/currentTarget
您可以使用 IDE/编辑器中的 IntelliSense(或等效工具)来确定类型。暂时将事件处理程序放置在 HTML 元素内,然后将光标悬停在该事件上。例如。
<button onClick={(event => console.log(event))}>Click me</button>
Run Code Online (Sandbox Code Playgroud)
将鼠标悬停event在 VSCode 中显示:
(parameter) event: React.MouseEvent<HTMLButtonElement, MouseEvent>
Run Code Online (Sandbox Code Playgroud)