-
Notifications
You must be signed in to change notification settings - Fork 319
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
LitElement hard to use with mixins in TypeScript because it's an abstract class #227
Comments
If anyone is interested, this is the workaround I currently use: import { LitElement as AbstractLitElement } from '@polymer/lit-element';
// Makes LitElement non-abstract so that it can be used in mixins
// @ts-ignore
export class LitElement extends AbstractLitElement {} I then import and extend this custom Only downside is the extra code that's generated, but it's minimal enough to me to warrant its usage. |
@asyncLiz will you make a codepen or jsbin or whatever example? |
I'm not sure how to add an online example since you'd need the TS compiler, but here's a full example you can copy/paste. import { LitElement, html } from '@polymer/lit-element';
// @ts-ignore
class FixedLitElement extends LitElement {}
type Constructor<T> = { new (...args: any[]): T };
function MyMixin<B extends Constructor<any>>(base: B) {
return class extends base {
isMixin = true;
};
}
// class MyElement extends MyMixin(LitElement) { // "Cannot assign an abstract constructor type to a non-abstract constructor type."
class MyElement extends MyMixin(FixedLitElement) {
constructor() {
super();
console.log(this.isMixin); // true from MyMixin
console.log(this.updated); // function from UpdatingElement
}
render() { // Will not compile if render() is not implemented
return html``;
}
} |
Thanks @asyncLiz for the example code. I've extended your example to use decorators and a constructor in the mixin. import { LitElement, customElement, property, html, Constructor as _Constructor } from "@polymer/lit-element"
// @ts-ignore
export class BaseElement extends LitElement {}
declare type Constructor<T> = {
new (...args: any[]): T
}
export function LoggerMixin<B extends Constructor<HTMLElement>>(baseClass: B) {
return class extends baseClass {
_log: (...message: any[]) => void
_info: (...message: any[]) => void
_debug: (...message: any[]) => void
_trace: (...message: any[]) => void
_warn: (...message: any[]) => void
_error: (...message: any[]) => void
constructor(...args: any[]) {
super(...args)
const message = `[${this.localName}] %s`
this._log = console.log.bind(console, message)
this._info = console.info.bind(console, message)
this._debug = console.debug.bind(console, message)
this._trace = console.trace.bind(console, message)
this._warn = console.warn.bind(console, message)
this._error = console.error.bind(console, message)
}
}
}
@customElement("foo-elem" as any)
export class Foo extends LoggerMixin(BaseElement) {
@property({ type: String })
label?: string
render() {
this._log(this.label)
return html`${this.label}`
}
} @sorvell The export declare type Constructor<T> = {
new (...args: unknown[]): T;
}; |
Fixed in #228 |
Because LitElement is an abstract class, it's hard to use with a mixin function that generates a class expression. Related issue: microsoft/TypeScript#5843.
To workaround this issue, perhaps LitElement should just not be an abstract class.
The text was updated successfully, but these errors were encountered: