Iterar sobre las propiedades de la interfaz en TypeScript

3 minutos de lectura

avatar de usuario
cris

Necesito mapear las propiedades de la interfaz a los objetos:

interface Activity {
  id: string,
  title: string,
  body: string,
  json: Object
}

actualmente hago:

headers: Array<Object> = [
  { text: 'id', value: 'id' },
  { text: 'title', value: 'title' },
  { text: 'body', value: 'body' },
  { text: 'json', value: 'json' }
]

Esto se vuelve muy repetitivo. Lo que me gustaría es algo como esto:

headers: Array<Object> = Activity.keys.map(key => {
  return { text: key, value: key }
})

No puede, las interfaces son solo para el tiempo de compilación porque javascript no lo admite.

Lo que puedes hacer es algo como:

const Activity = {
    id: "",
    title: "",
    body: "",
    json: {}
}

type Activity = typeof Activity;
const headers: Array<Object> = Object.keys(Activity).map(key => {
    return { text: key, value: key }
});

(código en el patio de recreo)

  • Tal vez una Q obvia: ¿cómo la segunda declaración de Actividad (como un tipo) no sombrea la primera declaración (como una const)?

    – Caminante libre

    23 de agosto de 2018 a las 9:08

  • @LukeWilliams El primero (const) la definición es un valor y la segunda es una definición de tipo. Si por ejemplo no vas a tener el segundo, y vas a hacer esto: let a: Activity; obtendrá el siguiente error: "Cannot find name 'Activity'". El compilador usará esas definiciones en los diferentes momentos/situaciones.

    – Nitzan Tomer

    23 de agosto de 2018 a las 13:59

  • ¿Podemos lograr lo mismo si queremos que el atributo de una interfaz sea opcional?

    – velociraptor11

    25 de marzo de 2020 a las 14:18

  • @ velociraptor11 no hay forma de traducir los tipos de tiempo de compilación al tiempo de ejecución, así que no. lo que puede hacer es filtrar de la matriz resultante todos los elementos que tienen undefined (o null) valores

    – Nitzan Tomer

    25 de marzo de 2020 a las 14:32

  • solo quita la linea type Activity = typeof Activity;. Object.keys solo funciona con objetos, no con tipos.

    – Sebastián Thees

    27 de abril de 2020 a las 18:47

Si está de acuerdo con que se agregue durante un tiempo de compilación y está usando TypeScript> = 2.4.1, puede probar la forma propuesta aquí.

Básicamente, debe agregar la dependencia ts-transformer-keys, transformador personalizadocomo uno básico y podrá enumerar las propiedades de esta manera:

import { keys } from 'ts-transformer-keys';

interface Props {
    id: string;
    name: string;
    age: number;
}
const keysOfProps = keys<Props>();

console.log(keysOfProps); // ['id', 'name', 'age']

  • ¿Y cómo puedo usar esto con un proyecto mecanografiado puro… uno sin webpack?

    – TacB0sS

    14 de noviembre de 2019 a las 20:46

  • Excelente sugerencia! Pude usarlo en un Gulp Script para compilar con bastante facilidad. Si necesita una referencia a mi fragmento, aquí tiene: github.com/Sitetheory/stratus/blob/…

    – Alex Gurrola

    25 de febrero de 2020 a las 19:44

  • si no está usando un paquete, la forma más fácil sería usar ttypescript. Simplemente instálelo y agregue el complemento a su tsconfig.json

    – T. Dayya

    16 de abril de 2020 a las 7:13

  • Demasiado difícil para trabajar create-react-app 🙁

    – Daniel

    6 jun 2021 a las 14:30

si desea mantener la capacidad de la interfaz, puede hacer lo siguiente, @Nitzan Tomer tiene razón. Las interfaces son parte del sistema de tipos, por lo tanto, solo son relevantes en tiempo de compilación, ya que se omiten en el código transpilado.

class Activity {
    public id: string = '';
    public title: string = '';
    public body: string = '' ;
    public json: Object = {};
}

let activity = new Activity()

const headers: Array<Object> = Object.keys(Activity).map(key => {
    return { text: key, value: key }
});

console.log(JSON.stringify(headers))

Este enfoque puede ser un poco exagerado, pero lo uso porque necesito esquemas JSON de todos modos para validar la estructura de respuesta del back-end. Obtener las claves de las interfaces es solo un buen efecto secundario de convertir interfaces mecanografiadas en esquemas json:

Usando un convertidor de esquema mecanografiado a json, uno podría obtener claves de interfaz junto con sus tipos. Los objetos json resultantes son grandes y detallados, por lo que una función auxiliar de análisis podría resultar útil para construir recursivamente objetos JS más simples de la forma que desee. La buena noticia es que un esquema json siempre tiene la misma estructura, por lo que es fácil de navegar.

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad