简体   繁体   中英

TypeScript dynamic class - combine/remove

I'm trying to make a dynamic class that is constructed using the components of many other possible classes.

I'm trying to add and remove them using ES6 Object.assign() and can get the variables to copy over but can't seem to get the methods to copy.

Here is an example of what I'm trying to do:

class foo {
  salad: string = 'salad';
  chop(){
    console.log('Chop');
  }
}

class man {
  nuts: string = 'nuts';
  kick(){
    console.log('Kick')
  }
}

class choo {
  add(){
    var f: foo = new foo();
    var m: man = new man();
    //Copy variables
    Object.assign(this, f, m);
    //Copy methods
    //Object.assign(this.prototype, f, m);
  }
  remove(){
    d = Object.getPrototypeOf(foo);
    for (key in d){
        delete this[key]
    }
  }
}

var karate = new choo();
karate.add();

//karate.chop();
console.log(karate.salad);
//karate.kick();
console.log(karate.nuts);

I tried to get an example to share on http://fiddlesalad.com/typescript/ but it wouldn't save. The code that is not working is commented out.

Object.assign(this.prototype, obj1) is what is recommended by ES6 to copy prototype functions from one class to another but TypeScript doesn't seem to like it.

Any ideas?

This is a total hack but it seems to do what you're looking for:

function extend < A, B > (d: A,
b: B) {
    for (var x in b) d[x] = b[x];
    return <A & B > d;
}

interface Object {
    assign < P, Q > (a: P,
    ...b: Q[]): P & Q;
}

interface ifoo {
    salad: string;
    chop();
}

interface iman {
    nuts: string;
    kick();
}

class foo implements ifoo {
    salad: string = 'salad';
    chop() {
        console.log('Chop');
    }
}

class man implements iman {
    nuts: string = 'nuts';
    kick() {
        console.log('Kick')
    }
}

class choo {
    foo: foo;
    man: man;
    add() {
        return extend(this, extend(this.foo = new foo(), this.man = new man()));        
    }
    remove() {
        Object.keys(this.man).forEach(k => delete this[k]);
        return <ifoo><any>this;
    }
}


let both = new choo();
var karate = both.add();
console.log("karate", karate);
karate.chop();
console.log(karate.salad);
karate.kick();
console.log(karate.nuts);

let chooman = both.remove();
console.log("karate", karate);
chooman.chop();

First off I'll point out that mixins are probably the correct answer to what I was looking to do.

Here is a good article about mixins:

https://www.stevefenton.co.uk/2014/02/TypeScript-Mixins-Part-One/

That being said, I did figure out a solution that uses Object.assign() although it's probably a bit frowned upon due to mutating __proto__ directly.

Choo will now look like this:

class choo {
  add(){
    var f: foo = new foo();
    var m: man = new man();
    //Copy variables
    Object.assign(this, f, m);
    //Copy methods
    Object.assign(this.__proto__, foo.prototype, man.prototype);
  }
}

remove() method was deleted because Object.assign() will overwrite class methods if they share the same name. Before testing I wasn't sure if there would be issues with that.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM