I've read this article. https://justinfagnani.com/2015/12/21/real-mixins-with-javascript-classes/
here is the original code of JavaScript from the article:
class MyClass extends mix(MyBaseClass).with(Mixin1, Mixin2) {
/* ... */
}
let mix = (superclass) => new MixinBuilder(superclass);
class MixinBuilder {
constructor(superclass) {
this.superclass = superclass;
}
with(...mixins) {
return mixins.reduce((c, mixin) => mixin(c), this.superclass);
}
}
I'm wondering how to create such a mixin utility helper in typescript so I can get the type hitting and static code analysis.
I've been tried hours... but couldn't finish it without using some any types, if I use any I miss all the type hints, which is not what I want.
You can use chaining, since otherwise all Mixins would have to have the same return signature using generics:
interface Ctor<T = NonNullable<any>> {
new(...params: any[]): T;
}
interface MixIn<Superclass extends Ctor, Extension extends Ctor> {
(ctor: Superclass): Superclass & Extension;
}
function mix<T>(superclass: Ctor<T>) {
return new MixinBuilder(superclass);
}
interface Mixed<T extends Ctor> {
with<K extends Ctor>(mixin: MixIn<T, K>): Mixed<ReturnType<MixIn<T, K>>> & ReturnType<MixIn<T, K>>;
}
class MixinBuilder<T extends Ctor> {
superclass: T;
constructor(superclass: T) {
console.log(superclass);
this.superclass = superclass;
}
with<K extends Ctor>(mixin: MixIn<T, K>): Mixed<ReturnType<MixIn<T, K>>> & ReturnType<MixIn<T, K>> {
const mixed = mixin(this.superclass);
return class extends mixed {
static with<K extends Ctor>(mixin: MixIn<typeof mixed, K>) {
return new MixinBuilder(mixed).with(mixin);
}
} as any;
}
}
Playground
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With