Flow: Type narrowing fails within arrow function declarations

Created on 10 Jun 2017  路  5Comments  路  Source: facebook/flow

Repro:

let x: Function | null = null;
const r = x ? () => x() : 'hi';

I would expect Flow to carry the type narrowing into () => x(), but it does not.

Most helpful comment

Ah ok.

All 5 comments

@btford use const instead of let. when x is mutable, _flow_ cannot assume that it's still a Function when you call it.

@madbence

This isn't true. Flow handles other let declarations just fine, even functions. For instance, this works just fine:

let x: Function | null = null;
const r = x ? x() : 'hi';

The behavior isn't exclusive to functions. The same problem exists for strings, for instance. Consider:

let x: string | null = null;
const r = x ? () => x.toUpperCase() : 'hi';

@btford the problem is that your x() call is wrapped in an anonymous function, and flow cannot assume that when you call r, x will hold the same value (ie. the refinement is invalidated inside that anonymous function). If you replace let with const in your example, it works just fine:

const x: Function | null = null;
const r = x ? () => x() : 'hi';

ps: if x is a function parameter, you can use experimental.const_params or just capture the value inside the function with a const variable:

function foo(x: Function | null):void {
  const x_ = x;
  const r = x_ ? x_() : 'hi';
}

Ah ok.

Super helpful, thanks @madbence

Was this page helpful?
0 / 5 - 0 ratings