Búsqueda de sitios web

typescript - Cómo convertir un valor "String" a "Type" en Angular 2


Quiero crear un menú lateral en una aplicación Ionic 2 donde el componente de navegación de la página se coloque en un archivo JSON externo obtenido con la ayuda de la función menuService.getMenu.

Mi estructura JSON:

"menu":[
        {
          "title":"Grid",
          "component":"GridPage"
        }
      ]

Mis Ts:

    this.menuService.getMenu().then((menu) => {
    this.menu = menu;
    });

    openPage(menu) {
      console.log("menu", menu.component);
      nav.setRoot(menu.component);
    }

El registro en la consola imprime la cadena GridPage. Intenté convertir usando Type como Type(menu.component). Pero mi resultado en la consola es una función con nombre anónimo. Alguien, por favor, ayúdeme a convertir la cadena JSON en un componente "Type" para que la navegación funcione.

Respuesta #1

Supongo que hay una manera de obtener el tipo de una clase a partir de una cadena, pero no lo sé (no uso TS). Una solución simple sería

crear un mapa de cadena a tipo

classes = {
  'MyClass1': MyClass1,
  'MyClass2': MyClass2,
  'Grid': Grid
}

y luego simplemente busca los tipos

class['Grid']

La desventaja es que necesitas conocer todas las clases compatibles de antemano.

Respuesta #2

No conozco Angular 2 en profundidad, pero en una aplicación bien estructurada es sencillo y factible obtener un Tipo usando una cadena, si conoces el nombre completamente calificado del Tipo dado:

let typeName = "GridPage";
let ComponentType = MyApp.Components[typeName];

Si estás recibiendo el siguiente tipo de error:

La firma de índice del tipo de objeto tiene implícitamente un tipo 'any'.

... entonces necesitarás hacer un type cast del espacio de nombres (objeto) precedente. Prefiero afirmar a any en este caso, ya que es más corto que definir una interfaz en línea para una firma de índice basada en cadenas, y efectivamente no pierdes ninguna seguridad de tipo:

let ComponentType = (MyApp.Components as any)[typeName];

Además, este enfoque también funciona perfectamente con módulos:

import * as Components from "./components";

let ComponentType = (Components as any)[typeName];

Artículos relacionados