web-dev-qa-db-fra.com

Obtenir les clés d'une interface TypeScript sous forme de tableau de chaînes

J'ai beaucoup de tables dans Lovefield et leurs interfaces respectives pour leurs colonnes. 
Exemple:

export interface IMyTable {
  id: number;
  title: string;
  createdAt: Date;
  isDeleted: boolean;
}

J'aimerais avoir les noms de propriétés de cette interface dans un tableau comme celui-ci:

var IMyTable = ["id", "title", "createdAt", "isDeleted"];

Je ne peux pas créer directement un objet/un tableau basé sur l'interface IMyTable, ce qui devrait suffire, car j'obtiendrais les noms d'interface des tables de manière dynamique. Par conséquent, je dois parcourir ces propriétés dans l'interface et en tirer un tableau.

Comment puis-je atteindre ce résultat.

36
Tushar Shukla

À partir de TypeScript 2.3 (ou devrais-je dire 2.4, car cette fonctionnalité contient un bug qui a été corrigé dans [email protected]), vous pouvez créer un transformateur personnalisé pour réaliser ce que vous voulez faire.

En fait, j'ai déjà créé un tel transformateur personnalisé, qui permet ce qui suit.

https://github.com/kimamula/ts-transformer-keys

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

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

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

Malheureusement, les transformateurs personnalisés ne sont actuellement pas si faciles à utiliser. Vous devez les utiliser avec l'API de transformation TypeScript au lieu d'exécuter la commande tsc. Il y a un problème demandant un support de plugin pour les transformateurs personnalisés.

22
kimamula

Ne peut pas. Les interfaces n'existent pas au moment de l'exécution. 

workaround

Créez une variable du type et utilisez Object.keys dessus ????

10
basarat

Vous devrez créer une classe qui implémentera votre interface, l'instancier puis utiliser Object.keys(yourObject) pour obtenir les propriétés.

export class YourClass implements IMyTable {
    ...
}

puis

let yourObject:YourClass = new YourClass();
Object.keys(yourObject).forEach((...) => { ... });
5
Dan Def

Vous devez répertorier les clés vous-même, mais au moins TypeScript appliquera IUserProfile et IUserProfileKeys auront exactement les mêmes clés ( Required<T> a été ajouté dans TypeScript 2.8 ):

export interface IUserProfile  {
  id: string;
  name: string;
};
type KeysEnum<T> = { [P in keyof Required<T>]: true };
const IUserProfileKeys: KeysEnum<IUserProfile> = {
  id: true,
  name: true,
};
1
Maciek Wawro

Au lieu de définir IMyTable comme dans l'interface, essayez de le définir en tant que classe. Dans TypeScript, vous pouvez utiliser une classe comme une interface.

Donc, pour votre exemple, définissez/générez votre classe comme ceci:

export class IMyTable {
    constructor(
        public id = '',
        public title = '',
        public createdAt: Date = null,
        public isDeleted = false
    )
}

Utilisez-le comme une interface:

export class SomeTable implements IMyTable {
    ...
}

Obtenir les clés:

const keys = Object.keys(new IMyTable());
0
Derek