2017-05-08 38 views
0

我大致有以下几点:检测是否点击了里面的反应成分或不打字稿

componentDidMount() {                                               
    document.querySelector('body')!.addEventListener('click', this.click); 
} 

click = (e: Event) => {                                               
    if (this.state.toggled) { 
    if (!ReactDom.findDOMNode(this.someRef).contains(e.target)) { 
     this.setState({ toggled: false }); 
    } 
    } 
}; 

render() { 
    return (<CustomElement 
    ref={(e) => { this.someRef = e; }}                                         
    />) 
} 

此代码正确检测用户是否点击内部或外部的CustomElement,到目前为止,一切顺利。

然而,tsc是不满意这点在所有:

error TS2345: Argument of type 'EventTarget' is not assignable to parameter of type 'Node'. 
    Property 'attributes' is missing in type 'EventTarget'. 

看着node_modules/typescript/lib/lib.d.ts这是有道理的,因为e.target是这似乎只定义添加和删除事件处理程序的功能的EventTarget。但是MDN表示e.target是“对派发事件的对象的引用”。这听起来更接近我想要的。

那么如何保留当前的工作功能,同时也让tsc变得快乐(而不仅仅是消除错误)呢?

回答

0

如何定义你的点击处理程序是这样的:

private click = (e: Event) => 
{ 
    if (e.target instanceof HTMLElement && !ReactDOM.findDOMNode(this.someRef).contains(e.target)) 
    { 
     if (this.state.toggled) 
     { 
      this.setState({ toggled: false }); 
     } 
    } 
} 

样品pen

+1

我对这里的好处有点不清楚,看起来像这样让沉默了错误,因此tsc现在会假定内部代码永远不会运行,因为它会考虑instanceof检查总是失败? – Letharion

+0

试试吧。我测试了建议的代码,它实际上总是成功,因为HtmlElement是其他元素的基础。它不会真正消除错误(不像铸造成任何东西) - 相反,它会执行有效的检查,如果它是真的,则继续。 – Amid

+0

我附上了一个例子供您检查。 – Amid

0

我发现了一个类似的讨论在typescript issue queue其中说,在这种情况下,类型断言为probably unavoidable

基本上事件目标是最一般的类型,它的元件是一个亚型,和HTML元素是的子类型那。如果你从DOM中取回了一些东西,我们通常不知道它是什么,你应该添加一个类型断言来“添加”关于特定DOM布局结构的特定外部知识。

例如,事件的.target可能不是元素(例如,您可以将事件侦听器添加到XMLHttpRequest中,而XMLHttpRequest没有getBoundingClientRect方法)。

因此,因为目标可能或可能不是Node就像我想要的,TS不能推断事实,我需要断言。

​​似乎是正确的解决方案。

相关问题