Skip to main content

touchstone.mixin_1

Home > @pebula/touchstone > Mixin

Mixin() function

Class mixin factory used for design-time and run-time.

When using mixin, multiple classes can be used to compose a single class that is returned with the composed functionally but also with the composed design time type.

Since JS does not support multi-inheritance we need to copy all the class members, both levels, static and instance. This means that:

  • There is NO prototype chain! - Mixin constructors DOES NOT run.

Loosing the prototype chain means we loose all of the reflected metadata (i.e. decorators) that exists on each mixin type including the proto-chain in each mixin type. To workaround this, we will also run special logic that manually aggregate the reflected metadata from all of the mixins and push it as reflected metadata of new class returned. This includes typescript design time metadata created when decorators are used and metadata produced by this library. If things overlap, the last mixin wins!

The return class comes fresh and clean with NO prototype chain (other then Object) and with the aggregated functionality of all mixins.

You can then use this class directly or extend it.

class MyClass extends Mixin(Jump, Walk, Eat) {
}

Since MyClass extends the mixed in class directly it will not include it as part of the prototype chain hence all reflected metadata will propagate to MyClass.

> Note that full metadata reflection of mixins is possible only when they are decorated with decorated create by DecoratorDomain. If not, reflected metadata from properties (flat, no descriptors) is lost since we don't know the property names to query for.

Signature:

export function Mixin<T, S>(...mixins: Array<S & Abstract<T>>): Type<T> & S {
class __MixinClass {
constructor(...args: any[]) {
executeConstructors(__MixinClass, this, args);
}
}

const constructors: Set<(...args: any[]) => void> = new Set();

MixinFw.mixIntoClass(__MixinClass, mixins, mixin => {
handleConstructors(mixin, constructors);
DecoratedDomain.extendDecoratorMetadata(mixin, __MixinClass);
}) as any;

if (constructors.size > 0) {
__MixinClass[mixedInClassesConstructors] = constructors;
}

return __MixinClass as any;
}

Parameters

Parameter

Type

Description

mixins

Array<S & Abstract<T>>

Returns:

Type<T> & S