New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Documented useDefineForClassFields #479
Conversation
useDefineForClassFields is incompatible with experimentalDecorators, see lit/lit#1985
Thank you for the PR! We've actually just landed a bunch of improvements to the docs around this issue in #516 which you can see live at https://lit.dev/docs/components/properties/#avoiding-issues-with-class-fields. Closing because I think this supersedes the need for your improvement, but please let us know if you find something in this area is still missing or confusing. |
Thanks and that's a lot more in depth, but it doesn't mention the |
Hi @KeithHenry. The engineer who wrote that section left the
Gives an error. Our preferred style is to initialize the field where we first declare it, and adding the |
@arthurevans @aomarks I'm aware of that, it should be in the documentation too. Yes, So // TS visible code
@property() name = 'No one'; However, this must not be initialised as a class field - that's the bit that breaks prototype setter decorators like // JS output
constructor() {
this.name = 'No one';
}
...
__decorate([property()], ExampleElement.prototype, 'name'); This makes the Meanwhile Or to put it another way - if you want to initialise a decorated property with So you can do this explicitly with // TS visible code
@property() declare name: string;
constructor() {
this.name = 'No one'; // You can now set order or break on this with source maps
} I think it might be better practice to use Either way Meanwhile I've put that in a new PR #583 |
TS can use class fields with decorators without turning off useDefineForClassFields at the cost of losing inline initialisation see lit#479 and lit/lit#1985 for discussion
// TS visible code
@property() declare name: string; I would be worried about what this syntax will mean when decorators are finally standardized. This seems like it should be a TypeScript error, because the |
Wow, Declared fields can't have initializers though, but other than that I think all we need from the declaration is the name, which we do get. It might be worth thinking about. Syntax is definitely doing to change for standard decorators. Authors will have to use the new |
useDefineForClassFields
is incompatible withexperimentalDecorators
, see lit/lit#1985There are two solutions, both should be covered by Lit's documentation:
useDefineForClassFields: false
to force this new feature off.declare
to tell TS not to emit inline class fields that block the decorator define function.