Skip to content

Error TS2729 should occur inside arrow function #61212

@steffen-4s1

Description

@steffen-4s1

🔎 Search Terms

  • ts2729
  • used before its initialization
  • arrow function in fields
  • useDefineForClassFields

🕗 Version & Regression Information

  • This is the behavior in every version I tried, and I reviewed the FAQ for entries about >= 5

⏯ Playground Link

https://www.typescriptlang.org/play/?useDefineForClassFields=true&target=11#code/MYGwhgzhAEBiD29oG8BQ1oAcCuAjEAlsNAGYECmIAJgILQC80A2gLoB0AtmJgBQ8CUDAHwp0GaABcAFgQhsI5AE4A3IuTZV4AsQF9+qMTnxFSFagCEGkmXIUq1GrfsN5CxYPAB2ECYuzAJeEUeTEUCZTAJcmg7VWByAC4UaE0kgWEY3wJPAHNoPRQdVB0gA

💻 Code

class Foo {
  public fieldA = [].map(() => {
    // access service inside arrow function shouldn't be work with useDefineForClassFields = true
    this.service.do()
    //   ^^^^^^^ expected error ts(2729)
  })

  public fieldB = this.service.do()
  //                   ^^^^^^^ Property 'service' is used before its initialization. (ts(2729))

  public constructor(private service: { do: () => string }) {}
}

Just for sake of completeness:

JavaScript output with useDefineForClassFields = true
class Foo {
  service;

  fieldA = [].map(() => {
    this.service.do();
  });

  fieldB = this.service.do();

  constructor(service) {
    this.service = service;
  }
}
JavaScript output with useDefineForClassFields = false
class Foo {
  constructor(service) {
     this.service = service;

     this.fieldA = [].map(() => {
       this.service.do();
     });

     this.fieldB = this.service.do();
  }
}

🙁 Actual behavior

Error Property 'service' is used before its initialization.(2729) only occurs for fieldB initialization.

🙂 Expected behavior

Error Property 'service' is used before its initialization.(2729) should also occur for fieldA initialization inside the arrow function.

Additional information about the issue

With useDefineForClassFields = true (which is the default) the generated JavaScript code in my example won't work, because service is accessed even though it is still undefined.

If I set the setting to false, as is done automatically for earlier targets, everything works. However, I would like to avoid using the old format for classes.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions