Skip to content

Class static block does not allow forward reference to static method #45932

Closed

Description

Bug Report

🔎 Search Terms

class static blocks, forward reference, incorrect compiler error

🕗 Version & Regression Information

4.4.2 + nightly (4.5.0-dev20210910)

  • I was unable to test this on prior versions because the feature is new in 4.4

⏯ Playground Link

Playground link with relevant code

💻 Code

class A {
    static {
        A.doSomething();
    }

    static doSomething() {
       console.log("gotcha!");
    }
}

🙁 Actual behavior

Compiler error in line 3: "Property 'doSomething' is used before its initialization.(2729)"

The code works as-is in native JavaScript, tested in Firefox Developer Edition.

The rewrites for class static blocks in Babel as well as in TypeScript itself also work. Both execute the static block's code at a time where static methods of the class are already available.

🙂 Expected behavior

No compiler error, because everything's fine.

A forward reference to a static field, however, should be an error (I guess).

Workaround

Fall back to the way class static blocks could be emulated before they were supported:
Define an unused #-private static constant whose initializer is an immediate-evaluating function.

class A {
    static #_ = (() => {
        A.doSomething();
    })();

    static doSomething() {
       console.log("gotcha!");
    }
}

Playground link for workaround

Looks ugly, but works in the desired execution order and produces no compiler error.

Possibly related issues

Activity

  1. fwienber commented on Sep 20, 2021

    @fwienber
    Author

    Any first evaluation / labels for this one? Maybe Ron Buckton (@rbuckton) or Zzzen (@Zzzen)?
    I hope the example code makes the case quite obvious.

  2. fwienber commented on Nov 10, 2021

    @fwienber
    Author

    Thank you for adding this to 4.6.0 milestone.
    I was just wondering why this still has the "needs investigation" label. Do you doubt this is a bug? Do you need further elaboration?

  3. andrewbranch commented on Nov 10, 2021

    @andrewbranch
    Member

    Issues are currently coming in faster than I can triage them. It looked like a probable bug to me but I know very little about class static blocks. If I were to take the time to be 100% confident that this is a bug, I would not have time to do the things that need to happen to release TypeScript 4.5. On the other hand, Ron will know if this is a bug within about 30 seconds. “Needs investigation” ~= “Looks suspicious but I defer to the assignee’s judgment, because they have more expertise than me, can devote more time to studying it than me, or both.” Sadly that doesn’t fit in a label.

  4. added
    BugA bug in TypeScript
    and removed
    Needs InvestigationThis issue needs a team member to investigate its status.
    on Nov 10, 2021
  5. rbuckton commented on Nov 10, 2021

    @rbuckton
    Contributor

    Methods should be accessible. Static fields and static blocks are deferred until the end of ClassDefinitionEvaluation after static and prototype methods are defined (including private static elements).

  6. fwienber commented on Mar 4, 2022

    @fwienber
    Author

    To motivate that this should really be included in the next milestone: It's even worse!
    I just found out that from a static code block, you cannot even reference a constant defined before the class:

    const FOO = "FOO";
    class Bar {
        static {
            console.log(FOO); // Variable 'FOO' is used before being assigned.(2454)
        }
    }

    Run in TypeScript Playground

    This results in the unjustified compile error "Variable 'FOO' is used before being assigned.(2454)", but if you still run it, works as it should, logging "FOO".
    For this additional case, I can't even think of a work-around, which makes this bug far more serious.

  7. Zzzen commented on Mar 6, 2022

    @Zzzen
    Contributor

    You are probably the first person in the world who use class static block with TypeScript.

  8. Zzzen commented on Mar 6, 2022

    @Zzzen
    Contributor

    To motivate that this should really be included in the next milestone: It's even worse!
    I just found out that from a static code block, you cannot even reference a constant defined before the class:

    const FOO = "FOO";
    class Bar {
        static {
            console.log(FOO); // Variable 'FOO' is used before being assigned.(2454)
        }
    }

    Run in TypeScript Playground

    This results in the unjustified compile error "Variable 'FOO' is used before being assigned.(2454)", but if you still run it, works as it should, logging "FOO".
    For this additional case, I can't even think of a work-around, which makes this bug far more serious.

    This is related to #44949. so, you are probably the second one.

  9. fwienber commented on Mar 30, 2022

    @fwienber
    Author

    This other Playground example is now also fixed when choosing TypeScript "nightly" (4.70-dev...)!
    Thanks again for making it work!

  10. locked as resolved and limited conversation to collaborators on Oct 21, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

BugA bug in TypeScriptFix AvailableA PR has been opened for this issue

Type

No type

Projects

No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions