在typescript中创建动态类实例

时间:2018-03-23 15:06:43

标签: typescript ecmascript-5

我正在使用webpack,typescript 2.8,es5。

我想从变量名创建动态类实例,例如:

protected handleAfterInit(page) : void 
{

    let instance: any;
    let pageName: string = this.capitalizeFirstLetter(page);

    console.log(pageName);

    instance = Object.create((window[pageName]).prototype);
    instance.constructor.apply(instance);

    console.log(instance);
}

其中pageName是一个变量(Home,About etc),并且这些类已经在页面顶部导入:

import { Home } from "./Home";
import { About } from "./About";

但是使用当前代码我收到错误:

  

无法读取属性'原型'未定义的

似乎没有窗口。{class}

是否可以在打字稿中做这样的事情?

3 个答案:

答案 0 :(得分:1)

由于您从模块导入类HomeAbout,因此它们不在window对象中。

最简单的方法是使用构造函数签名:

protected handleAfterInit(page: new () => any): void {
    let instance = new page()
}

如果您需要按名称访问页面,可以创建包含页面的地图,然后调用avbove方法:

pagesByName : { [name: string] :new () => any } = {Home, About};
protected handleAfterInitByName(pageName: string): void {
    this.handleAfterInit(this.pagesByName [pageName]);
}

此外,您可以将any中的new () => any替换为所有页面的基类,以便更好地进行类型检查。

答案 1 :(得分:0)

window[pageName]获取名为pageName的全局变量。

模块中的变量或导入不会创建全局变量,因此无效。

相反,您应该创建自己的地图:

const pages = {Home, About};
pages[pageName]

答案 2 :(得分:0)

如果要导入类,则应将它们放在自己的对象中,然后使用它来构造新实例:

const constructors = {Home, About, ...};
const instance = constructors[pageName](); // pageName should be 'Home', 'About' ...