2017-05-08 9 views
0

に反応する検出した場合、私は、次のおおよそ持っている:クリックが内側だったコンポーネントまたはないtypescriptです

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'. 

e.targetが唯一のイベントハンドラを追加および削除するための関数を定義するように見えるEventTargetあるので、これは、理にかなってnode_modules/typescript/lib/lib.d.tsを見てみます。しかし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

私は、型アサーションがprobably unavoidableである。この場合には言うtypescript issue queueで同様の議論が見つかりました:

は、基本的なEventTarget要素がサブタイプとなっている最も一般的なタイプであり、かつのHTMLElementはのサブタイプでありますそれ。 DOMから物事を取り戻す場合は、一般的にはわかりません。特定のDOMレイアウトの構造に関する特定の外部知識を「追加」するために型アサーションを追加する必要があります。

たとえば、イベントのtargetはElementではありません(たとえば、イベントリスナーをXMLHttpRequestに追加できます。また、XMLHttpRequestにはgetBoundingClientRectメソッドがありません)。

ターゲットは私が望むようにNodeかもしれないし、そうでないかもしれないので、TSは真実を推論することができず、私は主張する必要がある。

​​が正しい解決策です。

関連する問題