Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 9 additions & 7 deletions packages/reactive-element/src/decorators/custom-element.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,13 @@
*/
import {Constructor, ClassDescriptor} from './base.js';

const legacyCustomElement = (
tagName: string,
clazz: Constructor<HTMLElement>
) => {
window.customElements.define(tagName, clazz);
/**
* Allow for custom element classes with private constructors
*/
type CustomElementClass = Omit<typeof HTMLElement, 'new'>;

const legacyCustomElement = (tagName: string, clazz: CustomElementClass) => {
window.customElements.define(tagName, clazz as CustomElementConstructor);
// Cast as any because TS doesn't recognize the return type as being a
// subtype of the decorated class when clazz is typed as
// `Constructor<HTMLElement>` for some reason.
Expand Down Expand Up @@ -57,7 +59,7 @@ const standardCustomElement = (
*/
export const customElement =
(tagName: string) =>
(classOrDescriptor: Constructor<HTMLElement> | ClassDescriptor) =>
(classOrDescriptor: CustomElementClass | ClassDescriptor) =>
typeof classOrDescriptor === 'function'
? legacyCustomElement(tagName, classOrDescriptor)
: standardCustomElement(tagName, classOrDescriptor);
: standardCustomElement(tagName, classOrDescriptor as ClassDescriptor);
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,15 @@ suite('@customElement', () => {
const DefinedC = customElements.get(tagName);
assert.strictEqual(DefinedC, C0);
});
test('elements with private constructors can be defined', () => {
const tagName = generateElementName();
@customElement(tagName)
class C1 extends HTMLElement {
private constructor() {
super();
}
}
const DefinedC = customElements.get(tagName);
assert.strictEqual(DefinedC, C1);
});
});