如何使JS对象*成为一个TypeScript类实例

时间:2014-01-30 11:49:58

标签: javascript typescript

说我有以下课程:

export class MyClass {
    str: string = '';

    foo() {
        console.log(this.str);
    }
}

然后,在其他一些代码中:

var myObj = {
    str: 'Hello World';
}

如何将myObj转换为MyClass个实例,因此以下行有效:

myObj.foo();
// writes 'Hello World' to the console

(请注意,我无法更改myObj的创建,因为它是在另一个库中创建的)

*****编辑:*****

我仍在寻找解决方案。主要问题是MyClass引用了其他类,这些类可能引用了MyClass。它是我尝试转换为TypeScript类的整个对象图。

在每个类和每个属性中,我都知道它的类型,并且它与MyClass上定义的类和属性完全匹配。

5 个答案:

答案 0 :(得分:1)

也许是这样的:(我已将MyClass添加为JS代码)。

function becomeMyClass(o){
  var fn1=function(){
    var thing;
    MyClass.apply(arguments);
    //note: shallow copy only
    for(thing in o){
      if(Object.prototype.hasOwnProperty
        .call(o,thing)){
          this[thing]=o[thing];
      }
    }
  };
  fn1.prototype=Object.create(MyClass.prototype);
  return new fn1([].slice.call(arguments,1));
}
function MyClass(){
  this.str = "from myclass";
}
MyClass.prototype.foo=function(){
  console.log(this.str);
};
var myObj = {
  str:"from myObj"
}

myC = becomeMyClass(myObj);
console.log(myC.foo());//from myObj
console.log(myC instanceof MyClass);//true

答案 1 :(得分:1)

我认为最简单的解决方案,最易读的解决方案以及代码最少的解决方案只是映射它:

var myClass = new MyClass();
myClass.str = myObj.str;

myClass.foo(); 

如果str属性是必需的,您可以将其作为构造函数参数并将其减少一行......

var myClass = new MyClass(myObj.str);

myClass.foo();

更新

如果程序中有许多具有相同属性的类,也许您可​​以在类中封装这些属性。例如,如果所有类都具有属性name, nickname, avatar,则可以将它们包装到Profile类中。如果您需要从一个类中获取配置文件并将其添加到另一个类,这将为您提供一个映射属性。

但是,你最了解你的用例,所以你可能会对这个J avaScript port of auto-mapper感兴趣,如果属性都有相同的名字,它应该很容易映射你的东西:

答案 2 :(得分:1)

创建对象的其他库是否总是从函数返回该对象?您可以创建一个.d.ts定义文件,该文件定义特定函数返回MyClass。

答案 3 :(得分:0)

发现它,现在我正在使用以下实用程序方法:

export class Util {
    static become(obj: any, newClass: any) {
        obj.__proto__ = (<any>(new newClass())).__proto__;
    }
}

以下调用通过分配正确的原型将myObj转换为MyClass实例:

Util.become(myObj, MyClass);

也许还有另一种更优雅的方式,不涉及使用__proto__

答案 4 :(得分:0)

因为你说你有很多具有未知属性列表的对象,所以我认为你不能为MyClass编写一个构造函数来接受任意对象并从其属性创建一个MyClass实例。因此,您无法将myObj“转换”为MyClass的实例。

摆弄myObj的原型并不是一件好事。请参阅https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/proto

上的警告

这会让你使用duck typing:MyClass.foo.call(myObj);这只有在MyClass的方法只引用myObj上可用的属性时才会起作用,即你不希望MyClass的构造函数将任何其他属性设置为默认值值等等(因为在这种情况下,MyClass构造函数实际上从未运行过。)