Skip to content

@property decorator incompatible with tsconfig compilerOption useDefineForClassFields #10202

@killerfurbel

Description

@killerfurbel

Bug Description

Hello,

I created a custom element and defined a property. However, setting the property did not change the attribute value in DOM.

After debugging a lot, I think I've tracked this down to the typescript compiler. You can just use the simple example from the playground and add "useDefineForClassFields" = true in the compilerOptions.

Also, there is even a warning (but only in DEV mode - would have saved me some time....) in this case: https://github.com/SAP/ui5-webcomponents/blob/63de8f0aa13fc6bd92748cc7416cf873887c0de5/packages/base/src/UI5Element.ts#L280

However, as stated in the warning, the solution cannot be to "not use useDefineForClassFields" or "not use ES2022" (which will default useDefineForClassFields to true, see https://www.typescriptlang.org/tsconfig/#useDefineForClassFields)?

Following the documentation, you can easily fix the issue by just adding a declare to the property as this will not emit any JS Code. Since the JS Code (additional defineProperty() after the super-constructor was called, which already generates the getter and setters based on the element metadata):

...

@customElement({
  tag: "my-element",
  renderer: litRender,
})
export class MyElement extends UI5Element {
  @property()
  declare name?: string;

  render() {
    return html `
      <div>
          Hello, ${this.name || "World"}!
      </div>`
  }

...

The only downside is, that you cannot declare a default value for this property then... so if the default for name should be UI5, you would need to write:

...

@customElement({
  tag: "my-element",
  renderer: litRender,
})
export class MyElement extends UI5Element {
  @property()
  declare name?: string;

    constructor() {
        super();
        this.name = "UI5"; // default
    }

  render() {
    return html `
      <div>
          Hello, ${this.name || "World"}!
      </div>`
  }

...

So what's the best option to solve this issue? I think at least the documentation should address this issue and show the alternatives?

Affected Component

No response

Expected Behaviour

No response

Isolated Example

No response

Steps to Reproduce

...

Log Output, Stack Trace or Screenshots

No response

Priority

None

UI5 Web Components Version

2.4.0

Browser

Chrome

Operating System

No response

Additional Context

No response

Organization

No response

Declaration

  • I’m not disclosing any internal or sensitive information.

Metadata

Metadata

Assignees

No one assigned

    Labels

    TOPIC CorebugThis issue is a bug in the codedocumentationThis issue is about wrong documentation

    Type

    No type

    Projects

    Status

    New

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions