javascripttypescriptweb-componentcustom-elementlit

Implementing attributeChangedCallback in Typescript?


In this tutorial attributeChangedCallback is implemented like this:

// attribute change
attributeChangedCallback(property, oldValue, newValue) {

  if (oldValue === newValue) return;
  this[ property ] = newValue;

}

And I'm trying to convert it to Typescript and so far I have this:

// attribute change
attributeChangedCallback(property:keyof HelloWorldComponent, oldValue:any, newValue:any) {
    if (oldValue === newValue) return;
    this[ property ] = newValue;  
  }  
}

However this still creates the error:

Cannot assign to 'ATTRIBUTE_NODE' because it is a read-only property.ts(2540)
Cannot assign to 'CDATA_SECTION_NODE' because it is a read-only property.ts(2540)
Cannot assign to 'COMMENT_NODE' because it is a read-only property.ts(2540)
Cannot assign to 'DOCUMENT_FRAGMENT_NODE' because it is a read-only property.ts(2540)
Cannot assign to 'DOCUMENT_NODE' because it is a read-only property.ts(2540)

Thoughts?


Solution

  • Seems you are trying to assign to properties that are read-only and typescript always defaults to a type that includes read-only properties when it can't correctly infer the type of the property parameter

    This is a better fix

    class HelloWorldComponent extends HTMLElement {
    
      private attr1: string | null = null;
      private attr2: string | null = null;
    
      attributeChangedCallback(property: string, oldValue: string | null, newValue: string | null) {
        if (oldValue === newValue) return;
    
        switch (property) {
          case 'attr1':
            this.attr1 = newValue;
            break;
          case 'attr2':
            this.attr2 = newValue;
            break;
          // Handle other attributes if needed
          default:
            throw new Error(`Unhandled attribute: ${property}`);
        }
      }
    }