I don't know if this is of interest, but you can get marginally closer to generic mixins by using a swift inspired associated type kinda of trick:
abstract class Runable<T> {
context?: T; // Later we can lookup typeof Foo["context"]
protected abstract run(ctx: typeof this["context"]): Promise<void>
}
export class zip extends Mixin(Runable<{ baseDir: string }>) {
paths: string[];
constructor(...paths: string[]) {
super();
this.paths = paths;
// FWIW if you can attached .run here it *IS* type inferred (but zip would be incomplete less you drop abstract)...
// this.run = (ctx) => this.doRun(ctx);
}
// The Normal Way:
// a type annotation is needed - but the LSP will infill with automatic fix!
protected async run(ctx: typeof this["context"]): Promise<void> {
console.log("Zipping", this.paths, "in", ctx.baseDir);
}
}
I don't know if this is of interest, but you can get marginally closer to generic mixins by using a swift inspired associated type kinda of trick: