Skip to content
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

Requested type change to lightning.Component.Template #481

Open
itsjamie opened this issue May 15, 2023 · 2 comments
Open

Requested type change to lightning.Component.Template #481

itsjamie opened this issue May 15, 2023 · 2 comments
Assignees

Comments

@itsjamie
Copy link
Contributor

itsjamie commented May 15, 2023

It would be nice if the template pulled the extends of keys from TemplateSpecType, instead of from Element.TemplateSpec in the else case.

The reason for this is that you have public properties that are defined in the template based on bound properties.

If we switched to using a setter, we would have to change other locations that used the same bound property, but directly onto Element.TemplateSpec values.

static _template() {
  return {
     publicProp: this.bindProp('isLive', () => { logicToSetProp }),
     Container: {
        visible: this.bindProp('isLive'),
     }
  }
}

Right now, typescript fails and prevents the usage of the pattern.

/**
   * Type used for the return result of _template().
   *
   * All TemplateSpec properties are made optional. Nested TemplateSpec properties are also made
   * optional, except for the `type` propety which is made required.
   */
   export type Template<TemplateSpecType extends Element.TemplateSpec = Component.TemplateSpecLoose> = {
    [P in keyof TemplateSpecType]?:
      P extends ValidRef
        ?
          TemplateSpecType[P] extends Component.Constructor
            ?
              TemplateRequireType<TemplateSpecType[P]>
            :
              TemplateSpecType[P] extends Element.Constructor
                ?
                  Template<InstanceType<TemplateSpecType[P]>['__$type_TemplateSpec']>
                :
                  Template<Element<InlineElement<TemplateSpecType[P]>>['__$type_TemplateSpec']>
        :
          P extends keyof Element.TemplateSpec
            ?
              TemplateSpecType[P] // P is a Element property key
            :
              string extends P
                ?
                  any // Support Loose Elements: keyof loose Elements `P` will always be a `string`, so let anything go
                :
                  undefined // Otherwise allow the property to only be undefined
  };
@frank-weindel
Copy link
Contributor

This seems reasonable.

This was purposely disallowed because the setters are be executed before any children on the Component have been created and before the Component sub-classes' own constructor is called (which might set up special child accessor properties that might be needed by the setters). Often public setters on Components manipulate the children of the Component and so using them in the _template often results in exceptions because the expected children or properties haven't been created yet.

However the use cause of bindProp() was not considered. I'd rather take this a step further and only allow the special structure that bindProp() produces to be set in this case. What do you think about that?

@itsjamie
Copy link
Contributor Author

itsjamie commented May 16, 2023

Absolutely. Just having the bindProp signature would be more than adequate. Otherwise, you should likely be using the constructor or __init, or default properties to achieve it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: On Hold
Development

No branches or pull requests

2 participants