-
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
Document authoring mixins in TypeScript #829
Comments
here's how I have been defining my mixing: import { LitElement, property } from 'lit-element';
// or HTMLElement or other base class
type Constructor<T> = new (...args: any[]) => LitElement
interface ReadonlyInterface {
readonly: boolean;
}
type ReturnConstructor = new (...args: any[]) => LitElement & ReadonlyInterface
export function ReadonlyMixin<B extends Constructor> (Base: B): B & ReturnConstructor {
class Mixin extends Base implements ReadonlyInterface {
@property({ type: Boolean }) readonly: boolean = false;
}
return Mixin
} Looks similar but I wonder if the differences are significant. 🤔 |
TypeScript has added support for the mixin pattern. However, it does not work with the constructor type that is exported by LitElement (and which is also the one referenced in the first post of this issue). The TS compatible constructor type is export type Constructor<T = {}> = new (...args: any[]) => T; If you use that compatible constructor, you don't need to specify an output type, as TypeScript will be able to derive it. For an example of this pattern, see https://github.com/home-assistant/home-assistant-polymer/blob/dev/src/mixins/subscribe-mixin.ts @justinfagnani, do you know why the constructor type of LitElement is the way it is? |
I'm also interested on this! Right now I have: type Constructor<T> = new (...args: any[]) => T;
export const myMixin = () => <T extends Constructor<HTMLElement>>(
baseElement: T
) => {
class MyMixin extends baseElement {
@property({ type: Object })
public data: any;
// ...
}
return MyMixin;
}; |
A follow-up question: how do we annotate protected methods defined on the mixin, in a way that would make them overridable by the class extending that mixin? So far I only found the workaround with a dumb clas: microsoft/TypeScript#25163 (comment) Here is the code example illustrating what I want to accomplish: @justinfagnani @rictic I would really appreciate any advice on how to handle this case. |
@balloob I'm interested to know if you are able to build with For |
Regarding the above question, I submitted my research regarding available workarounds for TS mixins & protected methods to microsoft/TypeScript#17744 (comment) so we can discuss it there. |
It should be documented that if we use mixin classes, we must forgo the ability to publish them in a library with declaration files. microsoft/TypeScript#35822 |
The new docs website has a dedicated page: Closing as fixed. |
I have been looking for a small example of how to create a mixin, but there wasn't one.
So far I was able to come up with the following snippet:
Some things that I learned before I was able to make it work:
Constructor
type 🔖Overall it was a bit challenging to figure that out 😅 So the example would help a lot.
@justinfagnani @cdata can you please confirm if the code snippet above is correct? Also, do you have any other guidelines about how mixins should be written in TypeScript?
The text was updated successfully, but these errors were encountered: