Skip to content

Commit

Permalink
Fix incorrect appliance of mixins
Browse files Browse the repository at this point in the history
Mixins must be applied on the "parent" class, if any is available such that the target class still can overwrite methods defined in a mixin.
  • Loading branch information
aedart committed Feb 4, 2024
1 parent 420c2e8 commit a0863a7
Showing 1 changed file with 16 additions and 3 deletions.
19 changes: 16 additions & 3 deletions packages/support/src/mixins/mixin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,16 @@ export function mixin(...mixins: Mixin[])
throw new TypeError(`@mixin() can only by applied on classes - "${context.kind}" is not support`);
}

return mixins.reduce((
superclass: typeof target,
// It is important that given mixins are used to decorate the target's parent class and not
// the target itself. Therefore, we obtain the parent class or simply create a class, if
// no parent is available.
const parent: object = (Reflect.getPrototypeOf(target) !== Reflect.getPrototypeOf(Function))
? Reflect.getPrototypeOf(target)
: class {};

// Decorate the parent with given mixins.
const superclass: object = mixins.reduce((
superclass: typeof parent,
mixin: Mixin<typeof superclass>
) => {
// Return superclass, when mixin isn't a function.
Expand All @@ -38,6 +46,11 @@ export function mixin(...mixins: Mixin[])

// Perform actual mixin and return resulting class...
return mixin(superclass);
}, target);
}, parent);

// Finally, change target to inherit from the "superclass" and return it.
Reflect.setPrototypeOf(target.prototype, superclass.prototype);

return target;
};
}

0 comments on commit a0863a7

Please sign in to comment.