2017-05-11 1 views
17

Ich habe eine Menge Tabellen in Lovefield und ihre jeweiligen Schnittstellen für welche Spalten sie haben.
Beispiel:
Get Keys einer Typescript-Schnittstelle als Array von Strings

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

Ich möchte die Eigenschaftsnamen dieser Schnittstelle in einem Array wie diese haben:

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

ich kein Objekt/Array basiert auf der Schnittstelle machen kann IMyTable direkt das sollte den Trick machen, weil ich die Schnittstellennamen der Tabellen dynamisch bekommen würde. Daher muss ich über diese Eigenschaften in der Schnittstelle iterieren und ein Array daraus herausholen.

Wie erreiche ich dieses Ergebnis?

Antwort

4

Kann nicht. Schnittstellen existieren zur Laufzeit nicht.

Abhilfe

eine Variable vom Typ Erstellen und Verwenden von Object.keys auf es

+1

Sie wie meinen Sie dies: 'var abc: IMyTable = {}; Object.keys (abc) .forEach ((key) => {console.log (key)}); ' –

+3

Nein, weil dieses Objekt keine Schlüssel enthält. Eine Schnittstelle ist etwas, das TypeScript verwendet, aber im JavaScript verdampft, so dass keine Informationen mehr übrig sind, um "Reflektion" oder "Interspektion" anzuzeigen. Alles, was JavaScript kennt, ist, dass es ein leeres Objektliteral gibt. Deine einzige Hoffnung ist, auf (oder [fordere das] zu warten (https: // github.com/Microsoft/TypeScript/Probleme)) TypeScript enthält eine Möglichkeit, ein Array oder Objekt mit allen Schlüsseln in der Schnittstelle in den Quellcode zu generieren. Oder, wie Dan Def sagt, wenn Sie eine Klasse verwenden können, haben Sie die Schlüssel in Form von Eigenschaften in jeder Instanz definiert. – Jesper

+0

Sie würden auch eine Fehlermeldung von TypeScript in dieser Zeile erhalten: 'var abc: IMyTable = { } 'weil das leere Objektliteral nicht der Form dieser Schnittstelle entspricht. – Jesper

2

Sie eine Klasse machen müssen, dass Ihre Schnittstelle implementiert, es instanziieren und dann Object.keys(yourObject) verwenden, um die Eigenschaften zu erhalten.

export class YourClass extends IMyTable { 
    ... 
} 

dann

let yourObject:YourClass = new YourClass(); 
Object.keys(yourObject).forEach((...) => { ... }); 
+0

Funktioniert in meinem Fall nicht, ich müsste diese Eigenschaften der Schnittstelle auflisten, aber das ist nicht was ich will? Name der Schnittstelle kommt dynamisch und dann muss ich seine Eigenschaften bestimmen –

6

Ab Typoskript 2.3 (oder sollte ich sagen, 2.4, wie in 2.3 diese Funktion a bug enthält, die in [email protected] behoben wurde), können Sie eine benutzerdefinierte erstellen Transformator, um zu erreichen, was Sie tun möchten.

Eigentlich habe ich bereits einen solchen benutzerdefinierten Transformator erstellt, der Folgendes ermöglicht.

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'] 

Leider sind individuelle Transformatoren zur Zeit nicht so einfach zu bedienen. Sie müssen sie mit der TypeScript-Transformations-API verwenden, anstatt den Befehl tsc auszuführen. Es gibt an issue, die eine Plugin-Unterstützung für benutzerdefinierte Transformatoren anfordern.

+0

Danke für Ihre Antwort, ich sah und installierte diesen benutzerdefinierten Transformator gestern schon, aber da dies Typoskript 2.4 verwendet, das von mir nicht von jetzt an. –

+4

Hallo, diese Bibliothek erfüllt genau meine Anforderung, aber ich bekomme 'ts_transformer_keys_1.keys ist keine Funktion', wenn ich die genauen Schritte in der Dokumentation befolge. Gibt es einen Workaround? –

+0

Ordentlich! Denken Sie, dass es erweitert werden kann, um einen dynamischen Typparameter zu nehmen (Anmerkung 2 in der Readme)? – kenshin

1

Anstatt IMyTable wie in der Schnittstelle zu definieren, versuchen Sie, es als Klasse zu definieren. In Typoskripten können Sie eine Klasse wie eine Schnittstelle verwenden.

Also für Ihr Beispiel definieren/Ihre Klasse wie folgt erzeugen:

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

es als Schnittstelle verwenden:

export class SomeTable implements IMyTable { 
    ... 
} 

Get Tasten:

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