Flow: Inferred object type loses coverage after && operator

Created on 20 Nov 2016  路  3Comments  路  Source: facebook/flow

I'm not sure what's going on here, but annotating the object makes it work properly, so maybe it's something to do with sealed vs unsealed objects. I'm still confused Flow only misses the error after the use of the && operator, though.

const inferred = {
  x: '',
  y: '',
};

const a = inferred.y1; // error, as expected
const b = inferred.x && inferred.y1; // no error?

const declared = {
  x: ('': string),
  y: ('': string),
};

const c = declared.x && declared.y1; // error
const d = declared.y1; // error

See Try Flow.

bug coverage

All 3 comments

Flow is being a bit clever here. In the inferred case, since we know that inferred.x is '', and thus definitely falsey, the inferred.y1 in inferred.x && inferred.y1 is unreachable and thus not an error.

Compare the following:

const o = {p:''};
o.p && o.q;

to

const o = {p:'non-empty'};
o.p && o.q;

In the latter we know that o.p is truthy, so o.q is reachable and we error.

Similarly, when o has type {p:string}, flow "forgets" that o.p has the literal value '' and thus can't statically determine whether o.p is truthy or falsey and considers o.q reachable as well.

Long story short, this is expected and sound behavior.

Ah, interesting. Here's the original context in which I encountered it, which explains why I think this might still be a problem:

import React from 'react';

class inferred extends React.Component {
  state = {
    x: '',
    y: '',
  };

  handlePress() {
    this.setState({x: 'truthy'});
  }

  render() {
    const a = this.state.y1; // error, as expected
    const b = this.state.x && this.state.y1; // no error?
  }
}

In the above context, I think I should an error in one of the following places:

  • setState({x: 'truthy literal'})
  • this.state.x && this.state.y1

Ah, this is definitely a bug. We shouldn't assume that this.state.x is the literal string '' here. Thanks for the report!

Was this page helpful?
0 / 5 - 0 ratings