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

Constructor code broken since npm version 4.3.0-dev.20210408 with --target ESNext #45298

Closed
scharf opened this issue Aug 2, 2021 · 5 comments
Labels
Question An issue which isn't directly actionable in code

Comments

@scharf
Copy link

scharf commented Aug 2, 2021

Bug Report

Compiling the code below compiled with the --target ESNext option, an error is thrown.

🕗 Version & Regression Information

  • No problem up to npm version 4.3.0-dev.20210407
  • The problem first appears in npm version 4.3.0-dev.20210408

⏯ Playground Link

Cannot be reproduced in the playground (see #45297)

💻 Code

function writeVal(a: number, b: any): number {
    console.log(‘writeVal’, a, b);
    return a;
}
class TestClass {
    a: number;
    public b = writeVal(2, this.z);    
    constructor(public z: number) {
        this.a = writeVal(1, this.z);
    }
    public c = writeVal(3, this.z);
}

🙁 Actual behavior

throws

x.ts:7:33 - error TS2729: Property ‘z’ is used before its initialization.

7     public b = writeVal(2, this.z);
                                  ~

  x.ts:8:17
    8     constructor(public z: number) {
                      ~~~~~~~~~~~~~~~~
    ‘z’ is declared here.

x.ts:11:33 - error TS2729: Property ‘z’ is used before its initialization.

11     public c = writeVal(3, this.z);
                                   ~

  x.ts:8:17
    8     constructor(public z: number) {
                      ~~~~~~~~~~~~~~~~
    ‘z’ is declared here.


Found 2 errors.

🙂 Expected behavior

The created javascript file should be

function writeVal(a, b) {
    console.log('writeVal', a, b);
    return a;
}
class TestClass {
    constructor(z) {
        this.z = z;
        this.b = writeVal(2, this.z);
        this.c = writeVal(3, this.z);
        this.a = writeVal(1, this.z);
    }
}
@IllusionMH
Copy link
Contributor

Most likely related to #45076 which is intended change to align with ES behavior related to class fields, although change in defaults for ESNext is not documented.

Looks like playground uses its own defaults which override new default value of useDefineForClassFields which is specific for ESNext target. You can see this error in playground if you explicitly enable useDefineForClassFields

And if you execute compiled code in any supported browser, you will see that it logs undefined in both places that are marked as error because these fields are added before constructor body runs.

@scharf
Copy link
Author

scharf commented Aug 4, 2021

You can see this error in playground if you explicitly enable useDefineForClassFields

Well I think, if the user does not change any settings, the version should user the default behavior and not requiring doing some research to figure out what flags to change to properly mimic the default behavior...

@IllusionMH
Copy link
Contributor

Yes, it's unfortunately that this flag has different default depending on TS version and target which is hard to implement for playground, however I think it make sense to keep Playground defaults vs TS default in separate discussion - e.g. linked #45297 or Playground repo.

And it doesn't change explanation in paragraphs 1 and 3.

@RyanCavanaugh RyanCavanaugh added the Bug A bug in TypeScript label Aug 5, 2021
@RyanCavanaugh RyanCavanaugh added this to the TypeScript 4.5.0 milestone Aug 5, 2021
@RyanCavanaugh RyanCavanaugh removed the Bug A bug in TypeScript label Aug 5, 2021
@RyanCavanaugh RyanCavanaugh removed this from the TypeScript 4.5.0 milestone Aug 5, 2021
@RyanCavanaugh RyanCavanaugh added the Question An issue which isn't directly actionable in code label Aug 5, 2021
@RyanCavanaugh
Copy link
Member

Where are y'all in every other issue where someone complains that the TS defaults aren't aligned with their personal preferences? 😅 Anyway see #34787; ESNext is intentionally a "moving target" that generally opts you in to the most-spec-like behavior and unspecified properties can go to different defaults depending on that. The Playground just has checkboxes so there we have to do whatever the checkbox says.

@typescript-bot
Copy link
Collaborator

This issue has been marked as 'Question' and has seen no recent activity. It has been automatically closed for house-keeping purposes. If you're still waiting on a response, questions are usually better suited to stackoverflow.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Question An issue which isn't directly actionable in code
Projects
None yet
Development

No branches or pull requests

5 participants