Skip to content

Error TS2729 should occur inside arrow functionΒ #61212

Closed
@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