Lit TypeScript decorator issue
Asked Answered
D

1

5

I try to get into TypeScript by writing TS based Lit Elements, refactoring a very small project of mine.

However it starts to get frustrating since I don't see what's wrong with this code since it's reduced to nearly the same as a HelloWorld example and still gives errors:

import { LitElement, css, html } from 'lit';
import { customElement, property } from 'lit/decorators.js';

@customElement('student-ids')
export class StudentIds extends LitElement {

  @property()
  name = 'Somebody';

  render() {
    return html`
      <h1>Classroom Ids</h1>
      <p>Hello, ${this.name}!</p>
    `;
  }
}

In Chrome I get the error:

Uncaught (in promise) Error: The following properties on element student-ids will not trigger updates 
as expected because they are set using class fields: name. Native class fields and some compiled output 
will overwrite accessors used for detecting changes. 
See https://lit.dev/msg/class-field-shadowing for more information.
    at StudentIds.performUpdate (reactive-element.ts:1302:17)
    at StudentIds.scheduleUpdate (reactive-element.ts:1261:17)
    at StudentIds.__enqueueUpdate (reactive-element.ts:1233:25)

Taking a look at problems my IDE sees, I get the impression that my project is missing some packages or settings to solve this, since within the IDE I see errors at the decorators:

  • @customElement(): Unable to resolve signature of class decorator when called as an expression. The runtime will invoke the decorator with 2 arguments, but the decorator expects 1.ts(1238)

  • @property(): Unable to resolve signature of property decorator when called as an expression. Argument of type 'undefined' is not assignable to parameter of type 'Object | ClassElement'.ts(1240)

Any hints on what to change to solve this issue?

Dorcy answered 18/8, 2023 at 15:23 Comment(4)
I remember decorators being experimental and TS5 introducing a few breaking changes, what version of typescript are you using? Has lit been updated to support it?Kalpak
In your tsconfig.json, have you set experimentalDecorators to true and useDefineForClassFields to false as per lit.dev/docs/components/decorators/#decorators-typescript ?Sheerness
I don't do Lit, but isn't name a standard property on HTMLElementHankhanke
Was indeed using TS5, but saw that when I create a new Vite TS/Lit project they too use version 5, so that shouldn't be the cause of the problem. I also set the experimentalDecorators to true. That indeed fixed the problem, thanks.Dorcy
S
8

Updated answer for Lit 3.0

The prior answer still works, however since Lit 3.0, standard decorator support has been added. Make sure you are using TypeScript ≥ 5.2

This means if you are on Lit version 3 or higher, you can now set experimentalDecorators and useDefineForClassFields to their default values.

This will require you use standard decorators and add the accessor keyword. For your example above, all you need is the accessor keyword:

  @property()
  accessor name = 'Somebody';

If you want more details about migrating from experimental decorators to standard decorators, there is an upgrade guide: https://lit.dev/docs/v3/releases/upgrade/#standard-decorator-migration

Prior answer (for Lit 2 and Lit 3):

When using decorators in Lit, make sure to follow the guidance here: https://lit.dev/docs/components/decorators/#decorators-typescript

In your TypeScript tsconfig.json, make sure to set experimentalDecorators to true and useDefineForClassFields to false.

Sheerness answered 21/8, 2023 at 17:20 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.