8

Before anyone marks this as duplicate please read below,

My scenario doesn't just involve TypeScript but also Angular2.

Objective

I need a method in app.component.ts which takes a string(Class Name) and creates a instance of that. The classes exist in other ts files.

Now to the use case: I have a method getWidgetObjectFromClassName(className : string) : Object{} which needs to return the instances of the class name which is in string format. Now the problem,

I tried using NameSpace and doing let instance = new SampleNS['OtherName'](); (SampleNS is a namespace), works perfectly fine in the case of single file.

But Now i have multiple ts files lets say interfaces.ts, classes.ts, otherclasses.ts. Im using export namespace SampleNS{} in interface.ts all works, next in classes.ts using the /// <reference path="interfaces.ts" /> and same namespace SampleNS.

Now my method getWidgetObjectFromClassName(className : string) : Object{} is in xyz.ts, and now which import should i give?, my point being if i say `import {SampleNS} from './interfaces'. The problem here is i can only import a single file's namespace(even though its the same) hence im creating instance is limited to the import of that specific file namespace.

Plunker Link https://plnkr.co/edit/pt90F34KPsGoHDpSUQFD?p=preview

6
  • What about creating a file that exports all your component, then you need to just import this file with a namespace and then you should be able to refer to all components the same way? Commented Jul 1, 2016 at 5:47
  • 3
    "Before anyone marks this as duplicate please read below," - No, I prefer to judge whether things are duplicates by flipping a coin. Commented Jul 1, 2016 at 5:48
  • ok gunter...trying out ur solution will get back... Commented Jul 1, 2016 at 5:48
  • @GünterZöchbauer its not able to locate the class even if i do so, should i post a plunker? Commented Jul 1, 2016 at 7:02
  • Plunker would be great. Commented Jul 1, 2016 at 7:11

2 Answers 2

13

Use as with imports like

import * as widgets from './lib';
...
this.widgetInstance = new widgets[className](); 

Plunker example

I remember this from another answer but I couldn't find it to give some credit :-/

Sign up to request clarification or add additional context in comments.

1 Comment

As always u have been awesome!
4

You can use eval to create an object from the class name:

class SomeClass
{
    x: number;
    y: number;
    constructor() {
        this.x = this.y = 1;
    }

}



function getWidgetObjectFromClassName(className : string) : {}
{
    return eval("new " + className + "();");
}

console.log("%o", getWidgetObjectFromClassName("SomeClass"));

Playground here

6 Comments

This works perfectly fine, but now for my scenario, when i have my SomeClass on other ts files and even if i import it it cannot find it. Please Check
Probably you will need to include module or namespace: getWidgetObjectFromClassName("ModuleOrNamespace.SomeClass")
This is not a clean solution, but definitely works, Why downvote?
So far, the only solution I've found, thanks! Likely dangerous, though.
@Raffael could you explain why it is likely dangerous? Is it because ambiguity of the classname might cause the wrong class to be returned?
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.