2016-07-06 4 views
2

これはSSCCEです。以下のコード:strokeAsACatの関数呼び出しで文句Flowインターフェイスタイプでダイナミックタイプテストを実行する方法は?

// @flow  
'use strict'; 

declare interface ICat { 
    purr(): string; 
} 

class Animal { 
    askToBeStrokedAsACat() { 
     strokeAsACat(this); // Flow complains here 
    } 
} 

function strokeAsACat(a: ICat) { 
    a.purr(); 
} 


class Cat extends Animal { 
    purr() { 
     return 'purr'; 
    } 
} 

const cat = new Cat(); 
cat.askToBeStrokedAsACat(); 

...結果。 苦情が(簡潔にするために編集される):

property `purr` of ICat not found in class Animal 

苦情が妥当と理解されます。インタフェースはtranspiledされているので、

ICat. type referenced from value position 

プラス:代わりに、上記で失敗...

class Animal { 
    askToBeStrokedAsACat() { 
     if (this instanceof ICat) 
      strokeAsACat(this); 
    } 
} 

dynamic type testsに書かれているものによると、私は単純に次の操作を行うことができるはずです離れて、ICatは実行時に利用できませんので、上記の実行に失敗します:

ReferenceError: ICat is not defined 
このように

は、その時点でthisハンドルがICat様物体があることを確認する唯一の方法は、次の操作を行うことです。

class Animal { 
    askToBeStrokedAsACat() { 
     if (this instanceof Cat) 
      strokeAsACat(this); 
    } 
}  

...しかし、これはnominal, not structural typingで、使用の目的に反し

(this instanceof Cat) || (this instanceof BobCat) || (this instanceof Lynx) 

だから、私の質問は以下のとおりです:私はカップルよりICat-likeクラスを追加する場合、私のように私のダイナミック型テストを記述しなければならないとのインターフェースICat

  1. interfaceの構造的な動的テストを実行する方法はありますか?
  2. フローの苦情を効果的に消滅させるための方法がありますか?

マイFlowバージョンです:

$ npm ls --depth 0 | grep flow-bin 
├── [email protected] 

答えて

1

インタフェース

のための構造ダイナミック型テストを実行する方法はありません、それは不可能です。あなたはオブジェクトがプロパティを持っているかどうかをテストすることができ、それは関数ですが、実行時にそのシグネチャをどうやって知っていますか?

ほとんど必要ありません。たとえば、あなたのコードでは、AnimalaskToBeStrokedAsACatを空白のままにして、それをCatサブクラスに上書きすることができます。

+0

これはSSCCEなので、この特定の例では 'askToBeStrokedAsACat'をあなたが言うように' Cat'サブクラスに置くことができますが、実際のケースでは(これが縮小されたところで)コードに必要でしたベースクラスにとどまるもっと重要なのは、私はあなたが「実行時にその署名をどうやって知っているか」というあなたの推論が正しいとは思わない。すべてのフローアノテーションは実行時に破棄されますが、Flowがあらゆる種類の有用な型チェックをとにかく止めることはありません。 –

+0

フローは、コードが安全であり、期待通りに実行されることを証明するために実行時構成を分析します。実行時に何かをチェックする方法がない場合、Flowが推論する方法はありません。あなたがやっていることは安全です。 – vkurchatkin

関連する問題