import type { Constructor } from '../types'; /** * Mixin function type - takes a base class and returns an extended class */ export type MixinFn = (Base: TBase) => TResult; export function mixin(Base: T): T; export function mixin>(Base: T, m1: M1): ReturnType; export function mixin, M2 extends MixinFn>>( Base: T, m1: M1, m2: M2, ): ReturnType; export function mixin< T extends Constructor, M1 extends MixinFn, M2 extends MixinFn>, M3 extends MixinFn>, >(Base: T, m1: M1, m2: M2, m3: M3): ReturnType; export function mixin< T extends Constructor, M1 extends MixinFn, M2 extends MixinFn>, M3 extends MixinFn>, M4 extends MixinFn>, >(Base: T, m1: M1, m2: M2, m3: M3, m4: M4): ReturnType; export function mixin< T extends Constructor, M1 extends MixinFn, M2 extends MixinFn>, M3 extends MixinFn>, M4 extends MixinFn>, M5 extends MixinFn>, >(Base: T, m1: M1, m2: M2, m3: M3, m4: M4, m5: M5): ReturnType; export function mixin< T extends Constructor, M1 extends MixinFn, M2 extends MixinFn>, M3 extends MixinFn>, M4 extends MixinFn>, M5 extends MixinFn>, M6 extends MixinFn>, >(Base: T, m1: M1, m2: M2, m3: M3, m4: M4, m5: M5, m6: M6): ReturnType; /** * Applies the given mixins to a common base class. * * @param Base The base class to apply the mixins to. * @param mixins The mixins to apply sequentially. * @returns A class constructor with all mixins applied. * * @example * ```ts * class Dog extends mixin(Animal, FourLegged, Carnivore) {} * ``` */ export function mixin(Base: T, ...mixins: MixinFn[]): Constructor { return mixins.reduce((mix, applyMixin) => applyMixin(mix), Base as Constructor); }