Quiero convertir una cadena con un nombre de tipo a un tipo sin un mapeo explícito (necesito el tipo para una fábrica de componentes angulares).

Con un mapeo, esto es bastante sencillo:

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

El problema es que tengo muchos componentes que deben mapearse manualmente y sería bueno si pudiera omitir el mapa.

Soluciones que encontré, que lamentablemente no son posibles debido a la minificación:

  • usando eval () (también esto sería muy sucio e inseguro)

  • usando la ventana ['Type1']

El resto de las soluciones que encontré fueron en su mayoría hilos muertos o proporcionaron el mapeo como la mejor posibilidad. ¿Tiene alguna idea de cómo resolver esto? ¿Es esto siquiera posible?

5
Andifined 16 oct. 2018 a las 18:11

2 respuestas

La mejor respuesta

Así que se me ocurrió una buena solución gracias a la ayuda de @Julian: reemplacé el mapeo con un decorador de clase al que se le dio el tipo de cadena y anoté cada tipo que quiero generar con él. En la implementación del decorador, agregué el tipo al mapa, que ahora se llena dinámicamente.

Esta solución no evita el mapeo de cada componente manualmente, pero creo que es mucho mejor que mi solución anterior, ya que el mapeo ahora está en el mismo lugar que el componente y no se olvida tan fácilmente.

// 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); };
}
1
Andifined 24 oct. 2018 a las 14:46

Por lo que puedo ver, no se puede hacer sin muchas limitaciones. El nombre de una clase a menudo nunca es único.

El mapeo es una solución mucho más consistente y si no desea mapear todo manualmente, entonces escriba un script precompilado para crear el mapa. Usar la API reflectante de Typecript para anotar las clases también es una muy buena opción.

1
Julian 24 oct. 2018 a las 11:37