Search code examples
typescriptecmascript-5

Create dynamic class instances in typescript


I am working with webpack, typescript 2.8, es5.

I want to create dynamic class instances from variable names for example:

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);
}

Where pageName is a variable (Home, About etc) and those classes are already imported on top of the page:

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

But with current code I get an error:

Cannot read property 'prototype' of undefined

It seems that there is no window.{class}

Is it possible to do something like this in typescript?


Solution

  • Since you import the classes Home and About from a module they are not in the window object.

    The simplest way to do this, would be to use a constructor signature:

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

    If you need access pages by name you can create a map with pages and then call the avbove method:

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

    Also you can replace the any in new () => any with a base class for all pages to give yo better type checking.