Skip to content

Instantly share code, notes, and snippets.

@RobinRadic
Created October 25, 2017 11:50
Show Gist options
  • Save RobinRadic/8c4431aec26d1d79db158960c7a940d3 to your computer and use it in GitHub Desktop.
Save RobinRadic/8c4431aec26d1d79db158960c7a940d3 to your computer and use it in GitHub Desktop.
can assign constructor parameters to mixins as well
import 'reflect-metadata'
import * as assert from 'assert';
import { action, computed, observable } from 'mobx';
function Mixin<T>(...mixins): new(mixinsParameters?: { [key: string]: any }) => T {
// let current = mixins.length - 1;
class X {
constructor(mixinsParameters?: { [key: string]: any }) {
mixinsParameters = mixinsParameters || {};
mixins.forEach(mixin => {
let params = mixinsParameters[ mixin.name ] === undefined ? [] : mixinsParameters[ mixin.name ]
if ( mixin.call !== 'undefined' ) {
let pdp = Object.getOwnPropertyDescriptors(mixin.prototype)
let inst = mixin.call(this, params)
Object.defineProperties(this, pdp)
}
});
}
}
mixins.forEach(mixin => {
Object.assign(X.prototype, mixin.prototype);
})
return <any> X;
}
class DogMeta {
constructor(...args) {
console.log('DogMeta args', args);
}
@observable meta = {
name: 'foo',
age : 15
}
@action
setName(name) {
this.meta.name = name;
}
@action
setAge(age) {
this.meta.age = age;
}
@computed
get name(): string {return this.meta.name}
set name(name: string) { this.setName(name) }
@computed
get age(): number {return this.meta.age}
}
class DogFeatures {
constructor(...args) {
console.log('DogFeatures args', args);
}
@observable activity = {
walking: false,
sitting: true
}
@action
walk() {
this.activity.sitting = false;
this.activity.walking = true;
}
@action
sit() {
this.activity.walking = false;
this.activity.sitting = true;
}
dumpFeatures() {console.log(this)}
v
}
class BaseDog {
constructor(...args) {
console.log('BaseDog args', args);
}
bark() {
console.log('WOOF!')
}
alive: boolean = false
kill() {
this.alive = false;
console.log('YU KILLED DOGGY. U SAD MAN')
}
isAlive() { console.log(this.alive)}
revive() {
this.alive = true;
}
dumpBase() {console.log(this)}
}
interface IDog extends BaseDog, DogMeta, DogFeatures {}
class MyDog extends Mixin<IDog>(BaseDog, DogMeta, DogFeatures) {
constructor() {
// super()
super({
BaseDog : [ 'the', 'base', 'dog', 'args' ],
DogMeta : [ false, true, 'ugliy' ],
DogFeatures: [ 'dead' ]
})
this.dump()
// super.revive();
}
dump() {console.dir(this, { colors: true, showHidden: true, depth: 6 })}
}
function run() {
let dog = new MyDog();
dog.dump()
dog.setName('sweety');
assert.equal(dog.name, 'sweety')
assert.equal(dog.alive, true)
dog.sit();
dog.bark();
dog.kill();
}
run();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment