Mixins as class decorators in typescript/angular2

Danylo Mylian
2 min readOct 28, 2016

--

Mixin pattern also known as functional inheritance is meant to solve the problems caused by classical inheritance approach. This pattern is used to achieve multiple inheritance (we are assuming Angular2 components as a context).

As you may know, ES (and TS) does not have native support for multiple inheritance, so TS offers this little solution — Mixins · TypeScript (you may also be familiar with traits). As stated in the article, you should have little utility function in your runtime library:


function applyMixins(derivedCtor: any, baseCtors: any[]) {
baseCtors.forEach(baseCtor => {
Object.getOwnPropertyNames(baseCtor.prototype).forEach(name => {
derivedCtor.prototype[name] = baseCtor.prototype[name];
});
});
}

But what if we push this a little bit further and integrate it directly into angular components? The idea of annotations (decorators) is widely used by the framework (@Component, @Injectable, etc).

In this article — Angular 2, decorators and class inheritance — Medium you can dive deeper into the subject. But for now, let’s stick with class decorators. This simple snippet shows one:


export function CustomComponent(annotation: any) {
return function (target: Function) {
var parentTarget = Object.getPrototypeOf(target.prototype).constructor;
};
}

Having reference to the target function and annotation params, we can create Typescript mixin.

export function Mixin(baseCtors: Function[]) {
return function (derivedCtor: Function) {
baseCtors.forEach(baseCtor => {
Object.getOwnPropertyNames(baseCtor.prototype).forEach(name => {
derivedCtor.prototype[name] = baseCtor.prototype[name];
});
});
};
}

Which is cool, I think.

After definition of the custom decorator, we can use it on real components.

// mixins.ts// Disposable Mixin
export class Disposable {
isDisposed: boolean;
dispose() {
this.isDisposed = true;
}
}// Activatable Mixin
export class Activatable {
isActive: boolean;
activate() {
this.isActive = true;
}
deactivate() {
this.isActive = false;
}
}
// component.tsimport { Disposable, Activatable } from ‘mixins’;@Component({
selector: ‘element’,
template: `...`
})
@Mixin([Disposable, Activatable])
export class TableViewComponent implements Disposable, Activatable {
// Disposable
isDisposed: boolean = false;
dispose: () => void;
// Activatable
isActive: boolean = false;
activate: () => void;
deactivate: () => void;
constructor() {}
}

Tell me what do you think about this technique and inheritance (mixins, traits, composition) in general.

________________________

Update (22.04.2017)

Link to plunker with few mixins applied https://plnkr.co/edit/of5JJMH6GV0vWykc5UIs

Henri Podolski, Jackie Gleason, mischa molhoek, Sergey Vasko
check out.

________________________

References/further reading:
Mixins · TypeScript
angular2 — How are decorators (annotations) compiled in Typescript? — Stack Overflow
Angular 2, decorators and class inheritance — Medium
Class Decorators · Rangle.io : Angular 2 Training
Decorators & metadata reflection in TypeScript: From Novice to Expert (Part I)

--

--