Skip to content

control flow analysis incorrectly narrows type to never when type-guarded #45664

Description

@pomack

Bug Report

The new control flow analysis incorrectly narrows a type that is type-guarded to fallback to never in the else clause when they should either remove the type-guarded type or stay the original type if not explicitly typed earlier. They should only fallback to never when all types are exhausted (if enum or was an initial set of types).

🔎 Search Terms

control flow analysis
never
type narrowing
type guard

🕗 Version & Regression Information

  • This changed between versions 4.3.5 and 4.4
  • This is still a problem in 4.5.0 nightly as of 2021-08-31

⏯ Playground Link

Playground link for 4.3.5 (no error)

Playground link for 4.4.2 (error)

Playground link for 4.5.0-dev.20210831 (error)

💻 Code

interface Box {
    isSmallBox(): this is SmallBox;
    isLargeBox(): this is LargeBox;
    sayHello(): any;
}

interface SmallBox extends Box {
    sayHello(): string;
}

interface LargeBox extends Box {
    sayHello(): number;
}

const b: SmallBox|LargeBox = {
    isSmallBox() { return false; },
    isLargeBox() { return true; },
    sayHello() { return 0.7734; }
}

const isLargeBox = b.isLargeBox();

if(isLargeBox) {
    b.sayHello();
} else {
    b.sayHello();
}

🙁 Actual behavior

The last b.sayHello() has b as type never, causing an error.

🙂 Expected behavior

The last b.sayHello() should have b as type SmallBox

Metadata

Metadata

Assignees

No one assigned

    Labels

    Working as IntendedThe behavior described is the intended behavior; this is not a bug

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions