-
Notifications
You must be signed in to change notification settings - Fork 392
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
refactor(decorators): update decorator types @W-16373548@ #4429
Conversation
also, only allow @api on LightningElement classes
also, only allow on LightningElements
also, only allow on LightningElements
one file per decorator
/nucleus start |
TypeScript can't differentiate between a class without a superclass and a class that extends `any`. Because extending `any` is probably a fairly common use case (e.g. base components without a type stub), we need to allow it, at the cost of also allowing non-extended classes.
runtime behavior is to use "." as a delimiter, never as part of the property key
…lement Components could extend a superclass typed as `any`
/nucleus start |
/nucleus start |
/nucleus test |
/nucleus start |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This LGTM, but let's hold off on merging it until we've done the Nucleus/core analysis to know the scope of breakage, and are ready to release LWC v8. Awesome work.
// Helper props | ||
configProp = 'config' as const; | ||
nested = { prop: 'config', invalid: 123 } as const; | ||
'nested.prop' = false; // should be unused |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is kind of ambiguous because it's not clear whether $nested.prop
refers to line 130 or 131. Better to rename this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is deliberate, to validate that $nested.prop
picks up the object, rather than the weird prop name. I'll update the comment to clarify
These are nice improvements. These look specific to the wire, or does this also include better typing for |
These changes are specific to |
Details
This PR updates the types forDecided to not move forward with this change. Many users extend classes that are typed as@api
,@track
, and@wire
decorators to only work on components that extendLightningElement
. This is technically a breaking change, but should be of minimal impact because the decorators do not work on non-LWC components.any
, which is valid but does not satisfy theLightningElement
constraint.This PR also drops support for TypeScript's experimental decorators, requiring projects to use the modern, standard decorators (this is TypeScript's default since v5). This is also technically a breaking change, but because the LWC decorators are compiled into non-standard non-decorator code, the only requirement for pure LWC projects should be removing
"experimentalDecorators": true
from theirtsconfig.json
compiler options. This will be an impactful breaking change for LWC projects that use non-LWC experimental decorators on non-LWC classes. I don't know how many users that may be, but it feels like it's probably a small number?Additionally, this PR makes changes to the
@wire
decorator to improve type validation. Thewire
function now validates that the config provided matches the config expected by the adapter, and it validates that the type of the decorated property matches the value emitted by the adapter. In the current version of LWC (v7.2.0), the example below passes type validation. But with the changes in this PR, the latter two uses of@wire
would result in type errors.For bonus fun, reactive config props are accurately resolved! In the following example,
'$bookId'
is correctly resolved tonumber
, and would pass validation, while'$authorName'
is resolved tostring
, and would fail.Not immediately relevant to this PR, but worth calling out: TypeScript determines the type of the decorator from the type of the property, not the other way around. This means that for
@wire(getBook, config) book
, the type ofbook
cannot be inferred fromgetBook
;book
must always be explicitly typed.Does this pull request introduce a breaking change?
Does this pull request introduce an observable change?
GUS work item
W-16373548