我一直在寻找从Javascript中的字符串创建类,直到我遇到这个:
var instance = new window[classString]();
但是,这似乎不适用于Typescript,因为缺少类型信息。
详细信息:
interface SomeInterface{
structuredData: any;
}
class A implements SomeInterface {
}
我将JSON序列化类信息存储在数据库中。假设我有一个模型类A
,该类的属性在前端被序列化为JSON字符串,并与表示此数据的类名一起发送到数据库,即数据库包含一个class_type
列,其中包含类的名称。在这种情况下,这将是字符串' A'。现在,我想将这些数据恢复到我的应用程序中,并从该数据动态构造实例。
如果我们查看上面找到的Javascript实例化代码,我很乐意做这样的事情:
let instance = new window['A']();
instance.structuredData = foo;
由于这些类包含遵循某个接口的通用参数,因此我可以将序列化数据分配给那些新实例化的实例。
我正在使用Angular2 / Webpack,并且非常感谢有关如何执行此操作的任何提示。
当使用上面提到的代码时,我得到以下编译器错误:
不能使用' new'表达式类型缺少调用或 构建签名。
如果我尝试使用
规避严格的类型检查declare var window;
我收到以下错误:
window [' classString']不是构造函数
答案 0 :(得分:2)
由于Angular2巧妙地抽象了Webpack的参与,因此我并不确切知道如何加载和处理模块。但是,我的猜测(正如评论中所提到的)该类在窗口/全局空间中不可用,因此我提出了一个可能正确的解决方案(尝试过并且有效,但不确定是否这样做&#39 ; s是做这种事情的正确方法):
// first I require the module that is named in snake case with a .ts
// suffix based on the string that is stored in the database
// so if the stored string is SomeThing, we require the file
// called 'some_thing.ts'. Note: using lodash to generate that string
const dynModule = require('./' + _.snakeCase(classTypeString));
// next, we get the constructor by the class name from that module
// which is exactly the string that we stored in the db
const klass = dynModule[classTypeString];
// now we have the constructor function of the class and can
// instantiate a new class from that
let instance: SomeInterface = new klass();
instance.structuredData = foo;
答案 1 :(得分:1)
您可以自己将这些类放在窗口对象中,即使您在其他类中也是如此:
(window as any).example = class {}; // replace with you class
// and then later in code....
const classNameStr = 'example';
const init = new window[classNameStr]();
如果您不想在窗口对象内写入,则可以将它们存储在代码中的某个对象/字典中。 或者只是使用Eval(尽管使用它并不是一个好习惯):
eval(`new ${className}()`);