2017-04-04 1 views
0

Dire que j'ai une classe dactylographiée:Comment obtenir un tableau de noms de champs/propriétés publics?

class Person 
{ 
    constructor(public readonly firstName: string, public readonly lastName: string, public readonly id: number) 
    { 

    } 
} 

Je voudrais énumérer toutes les propriétés publiques de la classe donnée en utilisant une fonction générique.

Ainsi, les hypothétiques getAllPublicProps < ...> seraient utilisés comme ceci:

const allPublicProps: (keyof Person)[] = getAllPublicProps<Person>() ; 

et tableau de chaînes retour équivalent à [ 'prenom', 'lastName', 'id'].

Répondre

0

Il est quelque peu possible si vous pouvez accepter un peu de laideur, comme instancier la classe et accepter qu'il ne comprendra pas la distinction entre les propriétés privées et publiques (à moins que vous l'encodiez en quelque sorte).

Supposons que vous ayez votre classe

class Person { 
    constructor(public readonly firstName: string, 
       public readonly lastName: string, 
       public readonly id: number, 
       private readonly _secret: number) {} 
} 

Vous pouvez écrire une méthode util

class Util { 
    static getProperties(obj: any): string[] { 
    const result = []; 
    for (let property in obj) { 
     if (obj.hasOwnProperty(property) && !property.startsWith('_')) { 
     result.push(property); 
     } 
    } 
    return result; 
    } 
} 

et de l'utiliser

const allProperties = Util.getProperties(new Person()); 
+0

Merci pour la réponse, même si j'espérais que cela puisse être fait sans instancier l'objet. – user3284063

0

Sans connaître votre cas d'utilisation exact, il est difficile de vous donner une réponse concrète. Mais je vais essayer :)

Puisque les annotations de type TypeScript ne sont disponibles que pendant la compilation et non pendant l'exécution, il n'y a plus vraiment de différence entre les propriétés à la compilation. Par exemple:

class Person { 
    private secret = '123'; 
    constructor(
     public readonly firstName: string, 
     public readonly lastName: string, 
     public readonly id: number 
    ) { } 
} 

seront compilés à

var Person = (function() { 
    function Person(firstName, lastName, id) { 
     this.firstName = firstName; 
     this.lastName = lastName; 
     this.id = id; 
     this.secret = '123'; 
    } 
    return Person; 
}()); 

De plus, alors que type PersonProperties = keyof Person vous donnera une chaîne de type littérale de toutes les propriétés publiques, vous ne pouvez pas utiliser ce type de filtrer quoi que ce soit, parce qu'il est seulement une annotation. Vous ne pouvez donc utiliser que PersonProperties pour les signatures de fonction.

Supposons que vous puissiez utiliser Reflect, mais cela inclut le codage en dur des propriétés publiques. En outre, le compilateur d'Angular abuse du compilateur TS pour écrire des métadonnées disponibles pendant la compilation. Je ne sais pas s'il y a un framework agnostique lib qui fait la même chose.

+1

Merci, je l'ai aimé votre explication concernant « non métadonnées au cours runtime '; Cependant, la réponse de @ Hampus était un peu plus précise :) – user3284063