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?
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
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
.