简体   繁体   中英

Cast typename to type in typescript

I want to cast a string with a typename to a type without an explicit mapping (I need the type for an angular component factory).

With a mapping this is pretty straightforward:

public readonly typeMap: Map<string, Type<{}>> = new Map<string, Type<{}>>([
  ['Type1', Type1],
  ['Type2', Type2]
]);

The problem is that I have many components that need to be mapped manually and it would be nice if I were able to omit the map.

Solutions I found, that are sadly not possible due to minification:

  • using eval() (also this would be really dirty and unsafe)

  • using window['Type1']

The rest of the solutions I found were mostly dead threads or provided the mapping as the best possibility. Do you have any Ideas how to solve this? Is this even possible?

From what i can see it's not doable without lots of limitations. The name for a class is often never unique.

Mapping is a much more consistent solution and if you dont want to manually map everything then write a pre-build script to create the map. Using Typescript reflective API to annotate the classes is also a very good option.

So I came up with a nice solution myself thanks to the help of @Julian: I replaced the mapping with a class decorator that is given the type-string and annotated every type I want to generate with it. In the decorator implementation I then added the type to the map, that is now dynamically filled.

This solution does not get around mapping each component manually, but I think it is far better than my previous solution since the mapping is now at the same place as the component and is not as easily forgotten about.

// Empty mapping, filled at runtime
export const typeMap: Map<string, Type<{}>> = new Map<string, Type<{}>>();

// Classes that can be generated
@Type('Type1')
export class Type1 {}

@Type('Type2')
export class Type2 {}

// Decorator
export function Type(componentType: string) {
  return (target) => { typeMap.set(componentType, <Type<{}>>target); };
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM