Skip to content
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

The type checking doesn't work well in asynchronous code. #15148

Closed
fenying opened this issue Apr 12, 2017 · 1 comment
Closed

The type checking doesn't work well in asynchronous code. #15148

fenying opened this issue Apr 12, 2017 · 1 comment
Labels
Duplicate An existing issue was already created

Comments

@fenying
Copy link

fenying commented Apr 12, 2017

TypeScript Version: 2.2.2 / nightly (2.2.0-dev.201xxxxx)

Code

enum ETest {
    A,
    B,
    C
}

let g: ETest;

function test_a(): void {

    g = ETest.B;
}

(async () => {

    g = ETest.A;

    await new Promise(function(resolve, reject): void {

        setTimeout(resolve, 1000);
    });

    if (g === ETest.B) { // here will be marked as an error

        console.log("hey");
    }

})();

test_a();

Expected behavior:

That line shouldn't be marked as an error.

Actual behavior:

TS-compiler shows an error like this:

error TS2365: Operator '===' cannot be applied to types 'ETest.A' and 'ETest.B'.
16:33:07 - Compilation complete. Watching for file changes.

Maybe the strict type checking should be disabled for closured variables or this.xxxx?

@HerringtonDarkholme
Copy link
Contributor

This is related to how control flow analysis handles async/generator functions. They need special handling such as #11928.

However, code blocks in async/generator function are handled as if they were synchronous. This is pretty sweet if variable g is confined in async function, that is, g is only mutated inside async function, but it also breaks your code. We can also handle async/generator function as truly "async". But it breaks other inferences. For similar discussion, see #9998. I believe there is no silver bullet.

In this particular example, I would suggest finding a workaround which avoids changing g. Or, you can write a get_g function.

enum ETest {
    A,
    B,
    C
}

let g: ETest;

function test_a(): void {
    g = ETest.B;
}

function get_g() {
    return g
}

(async () => {

    g = ETest.A;

    await new Promise(function(resolve, reject): void {

        setTimeout(resolve, 1000);
    });

    if (get_g() === ETest.B) { // here will be marked as an error

        console.log("hey");
    }

})();

test_a();

@RyanCavanaugh RyanCavanaugh added the Duplicate An existing issue was already created label Apr 13, 2017
@mhegazy mhegazy closed this as completed Apr 19, 2017
@microsoft microsoft locked and limited conversation to collaborators Jun 21, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Duplicate An existing issue was already created
Projects
None yet
Development

No branches or pull requests

4 participants