Flow: Flow ignoring dynamic function validation check

Created on 8 Aug 2016  路  5Comments  路  Source: facebook/flow

flowtype: 0.30.0

Here is a simplification of the code I'm working with:

function checkValidLine(line: ?Object): boolean {
  return !! line;
}

function doStuff(line: Object) {
  // doing stuff
}

function myFunc(line: ?Object) {
    if (!checkValidLine(line)) {
      return;
    }

    doStuff(line);
}

Though I get the following error:

16:   doStuff(line);
       ^^^^^^^^^^^^^ function call
 16:   doStuff(line);
               ^^^^ null. This type is incompatible with
  7: function doStuff(line: Object) {
                            ^^^^^^ object type

The whole point is once I validated line to not be falsy, I know line is a valid Object. So my call to doStuff should expect line be a valid object. But flow does not seem to follow this check and so assumes line could still be falsy and thereby shows this error.

If I make this same check within myFunc, flow does not complain:

if (line) {
  doStuff(line)
}

But this defeats the point of using my validation function checkValidLine.

Any suggestions for best way to deal with these sort of situations?

refinements

Most helpful comment

Thanks for the report! Support for user-defined "predicate functions" such as checkValidLine is coming very soon (work is already underway). Until that feature is announced, though, yes unfortunately you have to inline the contents of such functions in your check.

All 5 comments

Thanks for the report! Support for user-defined "predicate functions" such as checkValidLine is coming very soon (work is already underway). Until that feature is announced, though, yes unfortunately you have to inline the contents of such functions in your check.

How far away do you think this is?

(Not complaining, its awesome you guys are doing what you're doing, but sadly I have too many other projects to get involved myself, so just wondering when you guys think it'll happen as it's forcing me to slow down on adopting Flow)

It's already there actually! Take a look at this example

That's awesome!
But wait, what version because I'm on 0.31.0 and it isn't working for me.
Was it introduces in 0.32? If not, then I might have a slightly different issue.

@vkurchatkin, @avikchaudhuri predicate functions don't seem to be supported yet for class methods (Flow 0.96.1):

// This predicate function works as expected
const isNumber = (val: string | number): boolean %checks => {
  return typeof val === 'number';
}

class TestVal {
  val: string | number;

  constructor(val: string | number) {
    this.val = val;    
  }

  // This predicate function does not seem to work within a class
  isNumber = (val: string | number = this.val): boolean %checks => {
    return typeof val === 'number';
  };

  getStringOrFail(val: string | number): string {
    if (this.isNumber()) {      // Line 24: Cannot return `val` because number [1] is incompatible with string [2]
//    if (isNumber(val)) {      // No errors
      throw new Error(`${val} is a number`)
    }

    return val;
  }
}

https://flow.org/try/#0PTAEBUAsEsGdQA4CcCmATaBjAhgFxaAGYCuAdprtAPamgDuVSA1vNvCgB4IoXoBQmGrFyg4AOWIBbAEYokoALygAFADdsAGwBcoYUmikA5qAA+oUlNlIAlDulUqGlNloBSTJB4tFAPlABvPlBQVFxiJFpcAE9uKkJQdQ1FBSUAcgsZOVSAbj4AXz4BDTZ4cBRhADVNAKCEzR09A2MzDKtc2sFSPWIKRjV63Vx9I1NzSzlrGoBIXBhYADpExTqNbODg2oLakAg5xFQMHHwiMgpqWjQqcvMqEVgUFElQXCp6RiZ6aFmDUGxQTGKsFgtXE43kSn62kGw2aY0y4Oec0WmlsoHsjmcbg8XngCj8gXWIRQYQizxiKDiK2SaVaWVywTy9NAtUMxIAykMmgB5JAAMWw0A0kIanJGLTBqMaIwJ62g8WU3wWoPhymsk38hOCOwAMgYCAAmAAsOgAwi5SLciSTaAADRI2tE8bDEe5wqygADaAEYALqieAGQSSBB4aDSJyfWbQpqe-U+vg7WXy5VWSFqgKa0A7MSvORIRjAzOzfN0cwoUsAUSQ+aQyhtABJ-Ik8v7fm65DbrLUGYVCaFwrREkyCnkgA

Was this page helpful?
0 / 5 - 0 ratings