Flow: Flow doesn't follow checks for possibly null/undefined value

Created on 28 Mar 2017  路  2Comments  路  Source: facebook/flow

Hey there!

It appears that flow is a bit overly aggressive in its treatment of null/undefined. In particular, it doesn't notice early returns (or perhaps mutual exclusivity) as a mechanism for guaranteeing "not null."

Here's an example:

interface Entity {
    id: ID,
    type: Type,
    version: ?Version,
};

const changes = {};

function stage (before: ?Entity, after: ?Entity) {
    if (!before && !after) {
        return;
    }

    changes[before ? before.id : after.id] = {
        before,
        after
    };
}

Flow errors on the reference to after.id, stating that:

  • id (property`id`) Property cannot be accessed on possibly null value after (null)
  • id (property`id`) Property cannot be accessed on possibly undefined value after (undefined)

You can see, however, that if either before or after is null/undefined, the other is necessarily NOT null/undefined.

Cheers,
Mike

bug

All 2 comments

Flow's refinement machinery is not designed to support cases like this. You can write your code slightly differently and Flow will happily follow along.

function stage (before: ?Entity, after: ?Entity) {
  let id = null;

  if (before != null) {
    id = before.id;
  }
  else if (after != null) {
    id = after.id;
  }

  if (id == null) return;

  changes[id] = {
    before,
    after
  };
}

Thanks for the reply and suggestion! I did end up refactoring to something similar, but left the issue open to document this unexpected (to me) behavior. It makes sense that this might require some pretty heavy logical inference that is currently outside the scope of flow. Hopefully this issue can help others surprised by this.

Was this page helpful?
0 / 5 - 0 ratings