【问题标题】:TypeScript dynamic class - combine/removeTypeScript 动态类 - 组合/删除
【发布时间】:2016-04-05 22:02:51
【问题描述】:

我正在尝试创建一个使用许多其他可能类的组件构建的动态类。

我正在尝试使用 ES6 Object.assign() 添加和删除它们,并且可以获取要复制的变量,但似乎无法获取要复制的方法。

这是我正在尝试做的一个示例:

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);

我试图在http://fiddlesalad.com/typescript/ 上分享一个示例,但它无法保存。不工作的代码被注释掉了。

Object.assign(this.prototype, obj1) 是 ES6 推荐的,用于将原型函数从一个类复制到另一个类,但 TypeScript 似乎不喜欢它。

有什么想法吗?

【问题讨论】:

  • 从表面上看,您正在尝试进行多重继承。我会先调查一下。注意:我不建议动态多继承,因为 Typescript 不会理解它。我还建议您查看生成的实际 js,看看为什么 Object.assign 不起作用。

标签: javascript typescript ecmascript-6


【解决方案1】:

这完全是 hack,但它似乎可以满足您的需求:

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();

【讨论】:

    【解决方案2】:

    首先我要指出,mixin 可能是我想要做的正确答案。

    这是一篇关于 mixins 的好文章:

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

    话虽如此,我确实想出了一个使用Object.assign() 的解决方案,尽管由于直接改变__proto__ 而可能有点不赞成。

    Choo 现在看起来像这样:

    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() 方法已被删除,因为Object.assign() 将覆盖类方法,如果它们共享相同的名称。在测试之前,我不确定这是否会有问题。

    【讨论】:

      猜你喜欢
      • 2012-09-17
      • 2019-07-11
      • 1970-01-01
      • 2015-05-21
      • 1970-01-01
      • 1970-01-01
      • 2020-12-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多