flow 0.35.0 "Function cannot be called on possibly undefined value" error after typeof === 'function' check

Created on 16 Nov 2016  路  2Comments  路  Source: facebook/flow

don't understand how i'm getting this error:

732:       this.gulp.task(gulpName, gulpDeps, function() { return fn(); });
                                                                  ^^^^ function call. Function cannot be called on possibly undefined value
732:       this.gulp.task(gulpName, gulpDeps, function() { return fn(); });
                                                                  ^^ undefined

in the following code (abridged):

setGulpTask(
    name: string,
    depsOrFn: Array<string> | Function,
    fn?: Function,
  ): void {
    // ...
    if (typeof fn === 'function') {
      this.gulp.task(gulpName, gulpDeps, function() { return fn(); });
    } else {
      this.gulp.task(gulpName, gulpDeps);
    }
  }

the usage of fn is inside a test for typeof fn === 'function', which i thought flow understood?

Most helpful comment

The problem is that function parameters can be reassigned, so flow can't be sure that when fn is called, that it's still valid. You can do something like that to avoid this problem:

setGulpTask(
    name: string,
    depsOrFn: Array<string> | Function,
    fn?: Function,
  ): void {
    // ...
    if (typeof fn === 'function') {
      const callback = fn;
      this.gulp.task(gulpName, gulpDeps, function() { return callback(); });
    } else {
      this.gulp.task(gulpName, gulpDeps);
    }
  }

All 2 comments

The problem is that function parameters can be reassigned, so flow can't be sure that when fn is called, that it's still valid. You can do something like that to avoid this problem:

setGulpTask(
    name: string,
    depsOrFn: Array<string> | Function,
    fn?: Function,
  ): void {
    // ...
    if (typeof fn === 'function') {
      const callback = fn;
      this.gulp.task(gulpName, gulpDeps, function() { return callback(); });
    } else {
      this.gulp.task(gulpName, gulpDeps);
    }
  }

thanks, that's basically how i ended up solving it.

i see why it is necessary...

function f(fn) {
  const newFn = function() {
    return fn();
  }

  fn = function() {
    return 'redefined';
  }

  return newFn;
}

const arg = function() { return 'defined'; };

f(arg)(); // => 'redefined'

sigh.... such is javascript i guess.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

ghost picture ghost  路  3Comments

ctrlplusb picture ctrlplusb  路  3Comments

jamiebuilds picture jamiebuilds  路  3Comments

bennoleslie picture bennoleslie  路  3Comments

mmollaverdi picture mmollaverdi  路  3Comments