How to convert a "String" value to "Type" in Angular 2
Solution 1
I guess there is a way to get the type of a class by string but I don't know (I don't use TS). A simple workaround would be to
create a map from string to type
classes = {
'MyClass1': MyClass1,
'MyClass2': MyClass2,
'Grid': Grid
}
and then just look the types up
class['Grid']
The disadvantage is that you need to know all supported classes in advance.
Solution 2
I don't know Angular 2 in depth, but in a well structured application it is straightforward and feasible to get a Type using a string, if you know the fully qualified name of the given Type:
let typeName = "GridPage";
let ComponentType = MyApp.Components[typeName];
If you are getting the following type error:
Index signature of object type implicitly has an 'any' type.
... then you will need to type cast the preceding namespace (object). I prefer asserting to any
in this case, as it's shorter than defining an inline interface for a string-based index signature, and you effectively don't lose any type-safety:
let ComponentType = (MyApp.Components as any)[typeName];
Additionally, this approach also works perfectly with modules:
import * as Components from "./components";
let ComponentType = (Components as any)[typeName];
Comments
-
AishApp almost 2 years
I want to create a side menu in ionic 2 application where the page navigation component is placed in a external json file fetched with the help of menuService.getMenu function.
MY JSON structure:
"menu":[ { "title":"Grid", "component":"GridPage" } ]
My Ts:
this.menuService.getMenu().then((menu) => { this.menu = menu; }); openPage(menu) { console.log("menu", menu.component); nav.setRoot(menu.component); }
Console log prints the string GridPage. I tried to convert using Type as Type(menu.component). But my result in console is a function with anonymous name. Someone please help me on getting the json string converted to component "Type" for navigation to work.
-
AishApp about 8 yearsHi @John White. i am getting "cannot read property 'GridPage' of undefined error" on using var check = (<any>this.app.Components)[typevar]; Kindly help
-
John Weisz about 8 years@Aish123 It means that
this.app.Components
is undefined. This is usually caused by file ordering issues if you compile into a single output file. If you are compiling into a single output file, try specifying reference paths for the compiler to know the correct file order. The error you are getting is not specific to getting types from strings. -
AishApp about 8 yearsI am not sure whether the command in supported in angular2 typescript. i am getting syntax error in ts. File order does not matter in my case as i am importing all my files on initializing my app.
-
John Weisz about 8 years@Aish123 What ts error do you mean? The "cannot read property ... of undefined" is not a Typescript compile error, it's a Javascript runtime error.
-
AishApp about 8 yearstypescript is not able to identify this.app.Components.
-
John Weisz about 8 years@Aish123 What error message are you getting during compilation?
-
AishApp about 8 yearsi am getting "Unresolved javascript functions" on components. I guess Angular2 is not identifying the function components. Do i have to import any package for it.
-
John Weisz about 8 years@Aish123 If you want to use a specific component type that was determined from a string, you will need to type cast. How else would the compiler know what type it is?
-
AishApp about 8 yearsActually the question is to convert string to a "Type". I didnt mean some other datatype here. Kindly check the doc. I have imported this Type from angular2
-
esqew almost 8 yearsThank you! Got me out of a bind. This should probably be the accepted answer.
-
John Weisz almost 7 years@JoseA This answer is more than a year old, nowadays it's preferred to use
obj as Type
instead (because<Type>obj
is ambiguous in.tsx
files). I've edited the answer accordingly. -
Jose A almost 7 years@JohnWeisz: Thanks. What about in the following scenario?: <MyType>(<any>document.getElementById('my-id').getAttribute('custom-attribute'). This is not in respect of Angular, but Web Components.
-
John Weisz almost 7 years@JoseA It would be simply
(document.getElementById('my-id').getAttribute('custom-attribute') as any) as MyType
, ordocument... as any as MyType
.