2017-01-12 4 views
2

私はthis exampleはです。TypeCheckていないことを確認するために驚いた:フローの細分化は「上向き」に伝播しませんか?

/* @flow */ 

type State = { flag: boolean } 

function firstStep(state: State) { 
    if (state.flag) { 
    secondStep(state) 
    // this works though: 
    // secondStep({ flag: state.flag }) 
    } 
} 

function secondStep(state: { flag: true }) {} 

3: type State = { flag: boolean } 
        ^boolean. Expected boolean literal `true` 
13: function secondStep(state: { flag: true }) {} 
           ^boolean literal `true` 

の流れは、それがtruestate.flagを絞り込むことができます知っているが、それはstate{ flag: true }に改良することができるということを知りません。それは期待されていますか?

答えて

1

表面上でよく見える多くのサブタイプの関係と同様に、これは変更可能性に欠けています。 secondStepは、stateへの参照を保持することができ、firstStepは、state.flagfalseに後で変更することができます。

しかし、これはあなたが使用している場合は動作しませんdisjoint unions:

type State = { flag: true } | { flag: false }; 

tryflow

あなたは、あなたがあなたのStateに異なる特性を持つことができるので、ばらばら組合は、より良いとにかくあなたのユースケースに合うことがありますオブジェクトはフラグの値に依存します。

この場合、Flowではstate.flagfalseに設定できないため、詳細はsecondStepに保持できます。

+1

'secondStep'は' secondStep'に 'state'への参照を保持できるので、' firstStep'は 'state.flag'をfalseに変更する可能性があります。もしあなたがunionの1つのブランチに入ったら、 'flag'が効果的に不変であるので、不規則なユニオンはそれを修正します。 –

+0

良いキャッチ。私はこの情報を含めるために私の答えを編集します。 –

+0

ああ、本当に面白い点@ライアンカバナフ。そのようなことが問題かどうか疑問に思っていました。バマー! –

関連する問題