There is an article on using and creating mix-ins on MDN (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/extends#mix-ins). I've tried to implement this in TypeScript:
type Constructor = new (...args: any) => any;
function nameMixin(Base: Constructor) {
return class extends Base {
#name?: string;
name() {
return this.#name;
}
setName(name: string) {
this.#name = name;
}
};
}
class None {}
class Foo extends nameMixin(None) {
constructor(private value: number) {
super();
}
}
const foo = new Foo(10)
foo.setName("john")
foo.name()
This seems to work pretty well but the one thing I don't particularly like about this trick is that I have to extend the arbitrary None class.
I've seen other people implement mix-ins with Object.assign(Foo.prototype, mixin), where mixin is an object, but I don't like that because it decouples the mix-in from the declaration.
Anyone know any other, cleaner ways of implementing mix-ins?
The, in my opinion, still most versatile pattern of the many different ways of accomplishing mixins in JavaScript is a function based mixin which is aware of a
thiscontext, thus it always gets applied viacallto the object in need of a mixed-in behavior.In addition of always working upon a delegated/bound
this, one, at apply time, can either pass variables like string and number values or even object-references which could be used as privately shared (even mutable) state amongst other such alike implemented mixins and the classes/factories which do create objects with mixed-in behavior.