Open
Description
export type Constructor<T> = new (...args: any[]) => T;
/*
static mixin<T extends object, U extends object, M1 extends object, I1 extends object>(
this: U & Constructor<T>,
m1: (superClass: U & Constructor<T>) => MixinClass<M1, I1>
): M1 & U & Constructor<T & I1>;
static mixin<T extends object,
U extends object,
M1 extends object,
I1 extends object,
M2 extends object,
I2 extends object>(
this: U & Constructor<T>, m1: (superClass: U & Constructor<T>) => MixinClass<M1, I1>, m2: (superClass: U & Constructor<T>) => MixinClass<M2, I2>): M1 & M2 & U & Constructor<T & I1 & I2>;
static mixin<T extends object,
U extends object,
M1 extends object,
I1 extends object,
M2 extends object,
I2 extends object,
M3 extends object,
I3 extends object>(
this: U & Constructor<T>,
m1: (superClass: U & Constructor<T>) => MixinClass<M1, I1>,
m2: (superClass: U & Constructor<T>) => MixinClass<M2, I2>,
m3: (superClass: U & Constructor<T>) => MixinClass<M3, I3>
): M1 & M2 & M3 & U & Constructor<T & I1 & I2 & I3>;
static mixin(...mixins: ((superClass: any) => MixinClass<any, any>)[]) {
// FIXME: workaround for https://github.com/Microsoft/TypeScript/issues/4130
const mixinBuilder = new MixinBuilder(this);
return (mixinBuilder as any).with(...mixins);
}
*/
export function mixin<T extends object, U extends object, M1 extends object, I1 extends object>(
superclass: U & Constructor<T>,
m1: MixinClass<M1, I1>
): M1 & U & Constructor<T & I1>;
export function mixin<T extends object,
U extends object,
M1 extends object,
I1 extends object,
M2 extends object,
I2 extends object>(
superclass: U & Constructor<T>, m1: MixinClass<M1, I1>, m2: MixinClass<M2, I2>): M1 & M2 & U & Constructor<T & I1 & I2>;
export function mixin<T extends object,
U extends object,
M1 extends object,
I1 extends object,
M2 extends object,
I2 extends object,
M3 extends object,
I3 extends object>(
superclass: U & Constructor<T>,
m1: MixinClass<M1, I1>,
m2: MixinClass<M2, I2>,
m3: MixinClass<M3, I3>
): M1 & M2 & M3 & U & Constructor<T & I1 & I2 & I3>;
export function mixin<T extends object, U extends object>(
superclass: U & Constructor<T>,
...mixins: MixinClass<any, any>[]
) {
return mixins.reduce((c, mixin) => mixin(c), superclass) as Constructor<T>
}
export type Properties<T> = { [K in keyof T]: T[K] };
export type MixinClass<T, P> = Properties<T> & Constructor<P>;
export class MixinBuilder<T extends object, U extends object> {
private superclass: Constructor<T> & U;
constructor(superclass: Constructor<T> & U) {
this.superclass = superclass;
}
with<M1 extends object, I1 extends object>(): Constructor<T & I1>;
with<M1 extends object, I1 extends object>(m1: MixinClass<M1, I1>): M1 & U & Constructor<T & I1>;
with<M1 extends object, I1 extends object, M2 extends object, I2 extends object>(
m1: MixinClass<M1, I1>,
m2: MixinClass<M2, I2>
): M1 & M2 & U & Constructor<T & I1 & I2>;
with<M1 extends object,
I1 extends object,
M2 extends object,
I2 extends object,
M3 extends object,
I3 extends object>(
m1: MixinClass<M1, I1>,
m2: MixinClass<M2, I2>,
m3: MixinClass<M3, I3>
): M1 & M2 & M3 & U & Constructor<T & I1 & I2 & I3>;
with(...mixins: Function[]): Constructor<T> {
return mixins.reduce((c, mixin) => mixin(c), this.superclass) as Constructor<T>;
}
}
Metadata
Metadata
Assignees
Labels
No labels