Why does typescript ignore modifications to locals in array callbacks?

Viewed 23

Specifically,

function foo(a: number[]) : number {
  let result = false;
  a.forEach((x) => {
    if (x === 5) {
      result = true;
    }
  });
  // Here ts reports:
  // "This condition will always return 'false' 
  // since the types 'false' and 'true' have no
  // overlap"
  if (result === true) {
    return 1;
  }
  return 0;
}

In the above, tsc believes that result cannot take the value true, despite the assignment inside the callback. Here's a playground link

I realize I could rewrite the above using eg Array#some, but in my real code I'm using map to produce a result, and this saves a second pass over the array just to set a flag.

Is there a way to make it recognize the fact that the callback may have been called?

1 Answers

You are only modifing result in another blocked scope (the foreach callback).

TS has no way to know when this callback is going to be called. It will depend on the implementation of the function.

There is an old open proposal to improve compiler understanding for immediatly-invoked methods.

Also, unless you're array is very big, always favor readability over premature optimisation, here map + some.

Related