feat(types): add hidden helper to make inferring element types better @W-18442478#5362
Merged
feat(types): add hidden helper to make inferring element types better @W-18442478#5362
Conversation
wjhsf
commented
May 5, 2025
packages/@lwc/template-compiler/src/parser/expression-complex/html.ts
Outdated
Show resolved
Hide resolved
jhefferman-sfdc
approved these changes
May 5, 2025
Contributor
|
Such a beautiful description, thank you! |
wjhsf
commented
May 6, 2025
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Details
When rendering an LWC component, the component instance and element instance are two connected but distinct objects. The component instance inherits from
LightningElement, while the element is an instance ofHTMLElementwith a few additional properties. Those properties are the@api-decorated properties from the component instance.When the class in the following example gets used, the component instance would have two props,
exposedandinternal. The element instance only has one,exposed.Because component authors create components, but largely consume elements, we added a new helper type in LWC v7.0.0 to bridge the gap. The new
LightningHTMLElementtype accepts a component interface and returns the corresponding element interface. However, it has a critical limitation. There is no way, in TypeScript, to distinguish decorated properties from non-decorated properties. And so, by default,LightningHTMLElementreturns an interface with all properties defined on the component, not just@api-decorated properties.The workaround originally provided for this was to explicitly provide the correct interface.
However, this approach is limited, as it must be done for every single usage of
createElement/LightningHTMLElement. More importantly, it requires the component consumer to provide the interface, rather than the component author. Thus, this PR introduces an new hidden/"fake" property that components can use. If a component defines__lwc_public_property_types__, then the type from that property is used as the public interface. This new property is "fake", in that it only exists as a hint to the type system; it never has a value at runtime. And it's "hidden" because it's not part of the publicLightningElementinterface, it's just sniffed by the helper type.Closes #4292.
Does this pull request introduce a breaking change?
Does this pull request introduce an observable change?
GUS work item