Skip to content

Execution order of static field initialization and static initialization blocks is not kept under target: esnext and useDefineForClassFields: falseΒ #45574

Closed

Description

@uhyo

Bug Report

πŸ”Ž Search Terms

class static initializer block esnext useDefineForClassFields

πŸ•— Version & Regression Information

4.4.1-rc, 4.5.0-dev.20210825

Static Initialization Blocks was newly introduced in TS 4.4.

⏯ Playground Link

Playground

πŸ’» Code

tsconfig.json

{
  "compilerOptions": {
    "target": "esnext",
    "useDefineForClassFields": false
  }
}

Code

class A {
  static foo = 123;
  static {
    console.log(this.foo); // should show 123
  }
}

πŸ™ Actual behavior

Following code is emitted. The line marked as // should show 123 would not print 123.

var _a;
class A {
    static {
        console.log(this.foo); // should show 123
    }
}
_a = A;
A.foo = 123;

πŸ™‚ Expected behavior

An emit such that execution order of the static field initialization and the static initialization block are kept.

static {} initialization blocks are evaluated in document order interleaved with static field initializers.

ECMAScript class static initialization blocks

Activity

  1. andrewbranch commented on Aug 25, 2021

    @andrewbranch
    Member

    Ron Buckton (@rbuckton) should we consider static initialization blocks incompatible with useDefineForClassFields: false, and/or error when they read static class fields under that setting?

  2. changed the title [-]Execution order of static field initialization and static initialization blocks is not kept under module: esnext and useDefineForClassFields: false[/-] [+]Execution order of static field initialization and static initialization blocks is not kept under target: esnext and useDefineForClassFields: false[/+] on Aug 25, 2021
  3. rbuckton commented on Aug 25, 2021

    @rbuckton
    Contributor

    Possibly. Or, we can change the emit for esnext when useDefineForClassFields is false to perform the assignments inside of a static {} block as well. I would caution that we only do that if there's already a static {} block on the class, though, since static {} is only shipping unflagged in the latest v8 currently. That way, you opt-in to using static {} for static field initializers when useDefineForClassFields is false if you're explicitly using the syntax in your class (since you're assumed to be running the code in an engine that supports that syntax).

    So, for example, our downlevel emit for the above could be:

    class A {
      static {
        this.foo = 123;
      }
      static {
        console.log(this.foo);
      }
    }
  4. 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 TypeScriptDomain: JS EmitThe issue relates to the emission of JavaScriptFix AvailableA PR has been opened for this issueRescheduledThis issue was previously scheduled to an earlier milestone

Type

No type

Projects

No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions