You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
CustomElementConstructor is missing observedAttributes #1338
The CustomElementConstructor interface defined in lib.dom.d.ts seems to be missing the observedAttributes static property (supported in all modern browser engines).
It's missing all the lifecycle callbacks too. It makes it tricky to derive custom element constructors without some workarounds.
functionderive(ctor: CustomElementConstructor){staticgetobservedAttributes(){return[...super.observedAttributes||[],"my-extra-attr"];// error, as above}attributeChangedCallback(...params: any[]){super.attributeChangedCallback?.(...params);// Property 'attributeChangedCallback' does not exist on type 'HTMLElement'.}}
This isn't as straightforward to fix as adding those properties to the interface, since the constructor is defined as returning a HTMLElement instance (which is obviously incorrect). I suspect this will become more of an issue as decorators become more widely used on custom element classes.
The interface should probably look something more like this:
NB: I've used any types here because, technically, you can register classes with different signatures and return values as custom elements. If narrow types were used, e.g. string[] for observedAttributes, it would restrict what you could pass to customElements.define()
I'd like to fix this. I've prepared a change that adds
observedAttributes?: readonly string[];
to CustomElementConstructor. I used readonly string[] rather than string[] so existing classes that use as const tuples or getters returning readonly arrays keep type-checking. I tested the example from this issue, as const, getters, classes without the property, and the derive-a-subclass pattern from Andy Earnshaw (@andyearnshaw)'s comment, and npm test passes.
On Andy Earnshaw (@andyearnshaw)'s note about narrow types: this does mean a class whose observedAttributes isn't a string list (e.g. a Set, which the spec technically allows) would now get a type error. If you'd rather avoid that, observedAttributes?: any would match his suggestion instead.
One implementation question: CustomElementConstructor is a callback function in the IDL, and emitCallBackFunction only emits signatures, so the simplest change adds the property line to its existing overrideSignatures in overridingTypes.jsonc. If you'd prefer, I can instead teach the emitter to support properties on callback functions. Which would you like?
The lifecycle callbacks raised in the thread change the constructor's return type, so I'd keep those out of this PR.
Activity
nolanlawson commentedon May 26, 2022
To clarify: the
observedAttributesproperty is optional, so my proposed change is:interface CustomElementConstructor { new (...params: any[]): HTMLElement; + observedAttributes?: string[]; }andyearnshaw commentedon May 25, 2023
It's missing all the lifecycle callbacks too. It makes it tricky to derive custom element constructors without some workarounds.
This isn't as straightforward to fix as adding those properties to the interface, since the constructor is defined as returning a
HTMLElementinstance (which is obviously incorrect). I suspect this will become more of an issue as decorators become more widely used on custom element classes.The interface should probably look something more like this:
NB: I've used
anytypes here because, technically, you can register classes with different signatures and return values as custom elements. If narrow types were used, e.g.string[]forobservedAttributes, it would restrict what you could pass tocustomElements.define()Ankith-B commentedon Oct 11, 2026
I'd like to fix this. I've prepared a change that adds
to
CustomElementConstructor. I usedreadonly string[]rather thanstring[]so existing classes that useas consttuples or getters returning readonly arrays keep type-checking. I tested the example from this issue,as const, getters, classes without the property, and the derive-a-subclass pattern from Andy Earnshaw (@andyearnshaw)'s comment, andnpm testpasses.On Andy Earnshaw (@andyearnshaw)'s note about narrow types: this does mean a class whose
observedAttributesisn't a string list (e.g. aSet, which the spec technically allows) would now get a type error. If you'd rather avoid that,observedAttributes?: anywould match his suggestion instead.One implementation question:
CustomElementConstructoris a callback function in the IDL, andemitCallBackFunctiononly emits signatures, so the simplest change adds the property line to its existingoverrideSignaturesinoverridingTypes.jsonc. If you'd prefer, I can instead teach the emitter to support properties on callback functions. Which would you like?The lifecycle callbacks raised in the thread change the constructor's return type, so I'd keep those out of this PR.