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

Bizarre circular type false positive #48708

Open
MichaelMitchell-at opened this issue Apr 14, 2022 · 7 comments
Open

Bizarre circular type false positive #48708

MichaelMitchell-at opened this issue Apr 14, 2022 · 7 comments
Labels
Bug A bug in TypeScript Help Wanted You can do this
Milestone

Comments

@MichaelMitchell-at
Copy link

MichaelMitchell-at commented Apr 14, 2022

Bug Report

🔎 Search Terms

implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer.(7022)

🕗 Version & Regression Information

This changed between versions 4.6.2 and 4.7.0-beta

⏯ Playground Link

Playground link with relevant code

💻 Code

type Wrapper = {
    data: number | null;
};

function example(wrapper: Wrapper) {
    // The error goes away if this line is removed and `null` is removed from the type
    if (wrapper.data === null) return;

    // The error goes away if the loop body is inlined o_O
    for (const _ of []) {
        const d = wrapper.data;
        //    ^ 'd' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer.

        // The error goes away without these lines o_O
        const t = d;
        const list = [0];
        if (list[t]) {}
    }
}

🙁 Actual behavior

Error: implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer

🙂 Expected behavior

No error

@MichaelMitchell-at
Copy link
Author

cc @ahejlsberg since you made some significant type flow analysis changes

@RyanCavanaugh RyanCavanaugh self-assigned this Apr 15, 2022
@andrewbranch andrewbranch added the Has Repro This issue has compiler-backed repros: https://aka.ms/ts-repros label Apr 26, 2022
@typescript-bot
Copy link
Collaborator

typescript-bot commented Apr 26, 2022

👋 Hi, I'm the Repro bot. I can help narrow down and track compiler bugs across releases! This comment reflects the current state of the repro in the issue body running against the nightly TypeScript.


Issue body code block by @MichaelMitchell-at

❌ Failed: -

  • 'd' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer.

Historical Information
Version Reproduction Outputs
4.2.2, 4.3.2, 4.4.2, 4.5.2, 4.6.2

👍 Compiled

@typescript-bot
Copy link
Collaborator

The change between 4.6.2 and Nightly occurred at 162713f.

@softwareCobbler
Copy link
Contributor

softwareCobbler commented Jun 12, 2022

Have a similar repro; was looking to file a bug and this seems like the right place for it.

interface A {
    a?: A
}

function foo(a: A) : void {
    let working : A | undefined = a;

    while (working) {
        // 'next_A' has type 'any' because it is referenced in its own initializer
        const next_A = working.a;
        if (next_A) {
            working = next_A;
        }
    }
}

playground link

@MichaelMitchell-at
Copy link
Author

I looked a bit into what part of 162713f caused this regression. It seems like adding isEntityNameExpression(expr.argumentExpression) to isNarrowableReference allows flowNodes to be set on expressions where they weren't previously during the binding phase. This in turn seems to lead to a circular type resolution when typing the expression along the getFlowTypeOfReference code path.

I haven't looked deep enough yet to understand why the circular type resolution happens yet, but I'm sharing my findings here in case it helps someone else pick up this investigation.

@MichaelMitchell-at
Copy link
Author

@Andarist you've been pretty capable at fixing random bugs I've stumbled upon before, so maybe this one would be of interest to you 😉

@RyanCavanaugh RyanCavanaugh added Bug A bug in TypeScript Help Wanted You can do this and removed Has Repro This issue has compiler-backed repros: https://aka.ms/ts-repros labels Dec 8, 2022
@RyanCavanaugh RyanCavanaugh added this to the Backlog milestone Dec 8, 2022
@RyanCavanaugh RyanCavanaugh removed their assignment Dec 8, 2022
@vassudanagunta
Copy link

vassudanagunta commented Jun 26, 2023

The error also goes away if you simply move just the initialization out of the loop:

type Wrapper = {
    readonly data: number | null;
};

function example(wrapper: Wrapper) {
    if (wrapper.data === null) return;

    const d = wrapper.data;
    for (const _ of []) {
        const t = d;
        const list = [0];
        if (list[t]) {}
    }
}

Also, per the Playground link, the change happened after 4.6.4. I presume 162713f is post 4.6.4?

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

No branches or pull requests

6 participants