web-dev-qa-db-fra.com

méthode «au moment de la compilation» pour obtenir l'interface de tous les noms de propriétés définis

Je voudrais créer une classe TypeScript générique pour le rendu (sous forme de liste HTML) d'un tableau d'objets qui implémentent un interface spécifique.

par exemple.

class GenericListRenderer<T> {
  items: T[];

 constructor(listItems: T[], className?: string){
      this.items = listItems;
      ...
    }

    private getPropertyNames(): string[]{

    // What is the best way to access all property names defined in
    // TypeScript interface 'T' that was used in this generic?
    ...   
    }

    render(){
      var propNames: string[] = this.getPropertyNames();
      // render list with each item containing set of all 
      // key(prop name)/value pairs defined by interface 'T'  
      ...

    }
}

Q: quelle serait la meilleure façon d'obtenir une liste "au moment de la compilation" de tous les noms de propriétés définis dans l'interface TypeScript spécifiée ()?

Comme les modèles C++, je crois que TypeScript pourrait résoudre ces génériques pendant le "temps de compilation", lorsque les informations de type TypeScript (comme une interface fournie au générique utilisé pour instancier un objet particulier) sont facilement disponibles.

Étant donné que toutes les informations de type requises sont potentiellement fournies, j'étais simplement curieux de savoir s'il y avait une extension/installation TypeScript disponible pour accéder à ces informations sans filtrage d'exécution excessif des objets Javascript `` Vanilla '' - ce qui pourrait être problématique en raison de problèmes d'héritage ambigus (par exemple, les propriétés d'interface héritées TypeScript peuvent être filtrées si l'environnement d'exécution, générique, Javascript (obj.hasOwnProperty (prop)) est utilisé pour filtrer les propriétés).

Ce potentiel d'introspection de propriété utile pourrait être résolu sans ambiguïté avec le super-ensemble de métadonnées de type de TypeScript pendant le "temps de compilation" par rapport à la tentative de résolution de ces informations dans le Javascript traduit, lorsque toutes ces informations de type sont rejetées.

Je détesterais "réinventer la roue" avec un hack Javascript potentiellement imparfait si une approche standard (TypeScript) existe.

25
user3413621

Cela est possible en utilisant des transformateurs personnalisés introduits par https://github.com/Microsoft/TypeScript/pull/1394 , qui est disponible dans TypeScript> = 2.4.1.

Mon package npm, ts-transformer-keys , est un bon exemple.

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

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

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

Il n'est pas possible de récupérer ces informations au moment de l'exécution, et elles ne seront jamais possibles par défaut, sauf si vous les stockez pendant la compilation. La solution est donc en réflexion en utilisant ReflectDecorators .

Ici est un excellent article couvrant la question de la récupération des métadonnées de temps de compilation au moment de l'exécution. En bref: vous ajoutez un décorateur à l'interface dont vous souhaitez conserver la description, celui-ci sera converti en un objet JSON qui sera stocké dans le code lui-même. Pendant l'exécution, vous pourrez récupérer cet objet JSON contenant toutes les données d'interface. C'est maintenant expérimental (11 février 2016) mais dans le bon sens.

Remarque: La raison pour laquelle il ne sera jamais par défaut essentiellement un choix de conception pour TS de ne pas surcharger le code js avec des métadonnées (contrairement à Dart).

6
Flavien Volken

Vous pouvez obtenir toutes les informations dont vous avez besoin en appelant

let test = Object.keys(instanceOfObject)

Si vous vous connectez console.log (test), vous obtenez quelque chose comme:

0: "user_id"
...
26: "address"
length: 27

vous pouvez accéder à toutes les informations sur cet objet, telles que test.length etc.

De: https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Global_Objects/Object/keys

0
Sethrone