2014-01-30 13 views
1

说我有下面的类:如何使一个JS对象*成为*一个打字稿类实例

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上定义的类和属性完全匹配。

回答

0

发现了这件事,我现在正在使用以下工具方法:

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

以下调用通过分配权原型转换myObjMyClass实例:

Util.become(myObj, MyClass); 

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

+1

如果碰巧在其他类的构造函数中有代码,它将不会被解雇,这使得这个解决方案在所有情况下都不一定是可移植的。您可能需要考虑将数据复制到新实例中。这样构造函数和属性设置者就有机会执行。 – WiredPrairie

+1

你不应该摆弄'''__proto__'''。它在ES5及其以下版本中是非标准的,即使在ES6中,也不鼓励自己设置它。 – Arnavion

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

我认为最简单的解决方案,最可读的解决方案和一个用线最少的代码是只映射它:

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

myClass.foo(); 

如果str属性是强制的,你可以使它构造函数的参数,并通过一条线减少这种...

var myClass = new MyClass(myObj.str); 

myClass.foo(); 

更新

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

但是,你知道你的使用情况最好的,所以你可能有兴趣在这个ĴavaScript port of auto-mapper,这应该很容易映射你的东西,如果属性都具有相同的名称:

+0

我正在寻找一种不会创建新对象的通用方法。我有很多对我想要转换的对象的引用,它们比只有一个属性'str'复杂得多。 – cheeesus

+0

属性名称是否始终匹配? – Fenton

+0

是的,属性名称始终匹配。 – cheeesus

1

是创建对象这个其他图书馆总是要从函数返回该对象?您可以创建一个.d.ts定义文件,该文件定义特定函数返回MyClass。

+0

但是在这种情况下'MyClass'构造函数将不会被执行,对吗?所以在使用'__proto__'时存在同样的问题。 – cheeesus

0

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

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

这使得你使用鸭打字警告:MyClass.foo.call(myObj);此,如果MyClass的的方法,只是指在MyObj中可用的属性,即只会工作,你不期望的MyClass的构造函数来设置的任何其他属性默认值等(因为在这种情况下,MyClass构造函数实际上从未运行)。

相关问题