export interface Constructor { new(...args: any[]): T; } export type MixinFunc = (baseClass: TBase) => TBase & MCls; export type MixinType> = InstanceType> export const mix = (superclass?: T): MixinBuilder => new MixinBuilder(superclass); export function MixClasses(A1: Constructor, A2?: Constructor, A3?: Constructor, A4?: Constructor, A5?: Constructor, A6?: Constructor, A7?: Constructor): Constructor { const mixins = [...arguments]; class MixedClass { constructor() { for (let cls of mixins) { Object.assign(this, new cls()); } } } for (let mixin of mixins) { for (let [key, desc] of Object.entries(Object.getOwnPropertyDescriptors(mixin.prototype))) { if (key == 'constructor') continue; Object.defineProperty(MixedClass.prototype, key, desc); } } return MixedClass as any; } // export function Mix(arg1: TBase, A1?: MixinFunc, A2?: MixinFunc, A3?: MixinFunc, A4?: MixinFunc, A5?: MixinFunc, A6?: MixinFunc, A7?: MixinFunc): (A1 & A2 & A3 & A4 & A5 & A6 & A7) & TBase { // const [base, ...args] = arguments; // return [...args].reduce((c, mixin) => mixin(c), base); // } class RootClass { } class MixinBuilder { constructor(superclass: TBase) { this.superclass = superclass || RootClass as any; } superclass: TBase; with(A1?: MixinFunc, A2?: MixinFunc, A3?: MixinFunc, A4?: MixinFunc, A5?: MixinFunc, A6?: MixinFunc, A7?: MixinFunc): (A1 & A2 & A3 & A4 & A5 & A6 & A7) & TBase { return [...arguments].reduce((c, mixin) => mixin(c), this.superclass); } } export default mix;