说我有以下课程:
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 :(得分: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构造函数实际上从未运行过。)