Skip to content

Erroneous control flow type narrowing in loops #15835

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
dead-claudia opened this issue May 14, 2017 · 4 comments
Closed

Erroneous control flow type narrowing in loops #15835

dead-claudia opened this issue May 14, 2017 · 4 comments
Labels
Bug A bug in TypeScript
Milestone

Comments

@dead-claudia
Copy link

TypeScript Version: 2.3.2

Code

const enum Escape {None, Any}

function scan(): void {
    let escape: Escape = Escape.None;

    while (true) {
        // Error: Operator '===' cannot be applied to types 'Escape.None' and 'Escape.Any'.
        escape = escape === Escape.Any ? Escape.None : Escape.Any;
    }
}

Expected behavior:

The type to be correctly broadened, since it's in a loop.

Actual behavior:

The error denoted in the code comment above the line in question.

@dead-claudia
Copy link
Author

Note that neither of these variants reproduce the bug:

// Variant 1
const enum Escape {None, Any}

function scan(): void {
    let escape = Escape.None as Escape;

    while (true) {
        escape = escape === Escape.Any ? Escape.None : Escape.Any;
    }
}

// Variant 2
function scan(): void {
    let escape = false;

    while (true) {
        escape = escape === true ? false : true;
    }
}

My current workaround is casting the escape in the condition, like in this:

const enum Escape {None, Any}

function scan(): void {
    let escape: Escape = Escape.None;

    while (true) {
        // No error here
        escape = (escape as Escape) === Escape.Any ? Escape.None : Escape.Any;
    }
}

Also, note that in my code, I have about 8-10 cases, for a while/switch-based finite state machine loop.

@JShabtai
Copy link

I just noticed what I believe is the same bug, but without the loop:

enum MyEnum {
    Foo,
    Bar
}

class MyClass {
    private state: MyEnum;

    // Set state to Bar
    private modify(){
        this.state = MyEnum.Bar;
    }

    public fn() {
        this.state = MyEnum.Foo

        this.modify();

        if (this.state === MyEnum.Bar) {
            // Do stuff here...
        }
    }
}

This produces the following error

tmp.ts(19,13): error TS2365: Operator '===' cannot be applied to types 'MyEnum.Foo' and 'MyEnum.Bar'.

Just tested this with tsc version 2.7.2

Seems that typescript doesn't think that variables of enum type can ever change?

@dead-claudia
Copy link
Author

@JShabtai Yours is subtly different:

  • Mine is purely with local variables, where yours is with properties.
  • Yours could change between checks, where mine theoretically couldn't.

@mhegazy mhegazy added this to the Future milestone Jul 21, 2018
@sandersn sandersn removed their assignment Jan 7, 2020
@RyanCavanaugh
Copy link
Member

Works now. Other comment is a dupe of 9998

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug A bug in TypeScript
Projects
None yet
Development

No branches or pull requests

5 participants