これは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
interface
の構造的な動的テストを実行する方法はありますか?- フローの苦情を効果的に消滅させるための方法がありますか?
マイFlow
バージョンです:
$ npm ls --depth 0 | grep flow-bin
├── [email protected]
これはSSCCEなので、この特定の例では 'askToBeStrokedAsACat'をあなたが言うように' Cat'サブクラスに置くことができますが、実際のケースでは(これが縮小されたところで)コードに必要でしたベースクラスにとどまるもっと重要なのは、私はあなたが「実行時にその署名をどうやって知っているか」というあなたの推論が正しいとは思わない。すべてのフローアノテーションは実行時に破棄されますが、Flowがあらゆる種類の有用な型チェックをとにかく止めることはありません。 –
フローは、コードが安全であり、期待通りに実行されることを証明するために実行時構成を分析します。実行時に何かをチェックする方法がない場合、Flowが推論する方法はありません。あなたがやっていることは安全です。 – vkurchatkin