Skip to content

Interaction between type guard function, loop, and destructuring causes type error in else block. #28758

Closed
@greim

Description

@greim

TypeScript Version: 3.2.1, 3.3.0-dev.20181129

Search Terms: else, guard, destructuring, for, of

Code

interface NumVal { val: number; }
interface StrVal { val: string; }
type Val = NumVal | StrVal;

function isNumVal(x: Val): x is NumVal {
  return typeof x.val === 'number';
}

function foo(things: Val[]): void {
  for (const thing of things) {
    if (isNumVal(thing)) {
      const { val } = thing;
      val.toFixed(2);
    } else {
      const { val } = thing;
      val.repeat(2); // <-- error occurs here
    }
  }
}

Expected behavior: Should compile.

Actual behavior: Fails to compile.

Playground Link: Playground Link

Related Issues: Closest I could find was this: #17023


Notes & observations: The error occurs in the else clause, near val.repeat(2). It seems like Intellisense disagrees with the type checker. Intellisense reports val of type string, but then it errors out because repeat is not available on type number. In the code, factoring out the loop, the type guard function, or the destructuring, causes the problem to go away:

Metadata

Metadata

Assignees

Labels

BugA bug in TypeScriptFixedA PR has been merged for this issue

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions