Gibt es eine Möglichkeit, den Typ der TypeScript-Schnittstelleneigenschaft zu „extrahieren“?

113

Nehmen wir an, es gibt eine Typisierungsdatei für Bibliothek X, die einige Schnittstellen enthält.

interface I1 {
    x: any;
}

interface I2 {
    y: {
        a: I1,
        b: I1,
        c: I1
    }
    z: any
}

Um mit dieser Bibliothek arbeiten zu können, muss ich ein Objekt übergeben, das genau vom gleichen Typ ist wie I2.y. Ich kann natürlich eine identische Schnittstelle in meinen Quelldateien erstellen:

interface MyInterface {
    a: I1,
    b: I1,
    c: I1
}

let myVar: MyInterface;

aber dann habe ich die Last, es mit dem aus der Bibliothek auf dem neuesten Stand zu halten, außerdem kann es sehr groß sein und zu viel Codeduplizierung führen.

Gibt es daher eine Möglichkeit, den Typ dieser spezifischen Eigenschaft der Schnittstelle zu "extrahieren"? Ähnliches wie let myVar: typeof I2.y(was nicht funktioniert und zu dem Fehler "Name I2 kann nicht gefunden werden" führt). Danke im Voraus.


Bearbeiten : Nachdem ich ein bisschen in TS Playground gespielt habe, habe ich festgestellt, dass der folgende Code genau das erreicht, was ich will:

declare var x: I2;
let y: typeof x.y;

Es muss jedoch eine redundante Variable xdeklariert werden. Ich suche nach einem Weg, dies ohne diese Erklärung zu erreichen.

Kuba Jagoda
quelle
1
was nicht funktioniert - wie manifestiert sich das? Was ist die tatsächliche Fehlermeldung, die Sie sehen?
Bartek Banachewicz
@BartekBanachewicz aktualisiert
Kuba Jagoda

Antworten:

230

Früher war es nicht möglich, aber zum Glück ist es jetzt seit TypeScript Version 2.1 . Es wurde am 7. Dezember 2016 veröffentlicht und führt indizierte Zugriffstypen ein, die auch als Nachschlagetypen bezeichnet werden .

Die Syntax sieht genauso aus wie der Elementzugriff, wird jedoch anstelle von Typen geschrieben. Also in deinem Fall:

interface I1 {
    x: any;
}

interface I2 {
    y: {
        a: I1,
        b: I1,
        c: I1
    }
    z: any
}

let myVar: I2['y'];  // indexed access type

Hat jetzt myVarArt von I2.y.

Probieren Sie es in TypeScript Playground aus .

Michał Miszczyszyn
quelle
1
Gibt es eine Möglichkeit, den Typ der Elemente zu extrahieren, wenn 'y' ein Array ist? zB I2 {y: {..} []}
John B
1
@JohnB Ja, Sie können dies genauso tun, da Array-Indizes genau wie Objekteigenschaften sind. Überprüfen Sie es hier: typescriptlang.org/play/…
Kuba Jagoda
1
@ JohnB ja, Sie können auf die gleiche Weise darauf zugreifen, dh. I2['y'][0]Siehe: typescriptlang.org/play/...
Michał Miszczyszyn
2
Das ist wirklich eine großartige Fähigkeit
Geradlus_RU
1
Nehmen wir an, wir durchlaufen die Schlüssel eines Objekts, das I2als Typ definiert wurde. Wie würde ich den Typ eines bestimmten Schlüssels beim Schleifen dynamisch erhalten? Dies; let z: typeof x[a];, wo aein bestimmter Schlüssel als String ist, funktioniert nicht. Es sagt mir, dass asich das auf einen Wert bezieht und sich auf einen Typ beziehen muss. Wie würde ich das machen? Ist das überhaupt möglich? Danke!
Emil Walser
-1

Eine Schnittstelle ist wie die Definition eines Objekts. Dann ist y eine Eigenschaft Ihres I2-Objekts, die von einem bestimmten Typ ist, in diesem Fall "anonym".

Sie können y auch über eine andere Schnittstelle definieren und dann wie folgt als y-Typ verwenden

interface ytype {
   a: I1;
   b: I1;
   c: I1;
}

interface I2 {
    y: ytype;
    z: any;
}

Sie können Ihre Benutzeroberfläche in eine Datei einfügen und Extrakt verwenden, um sie in andere Dateien Ihrer Projekte zu importieren

export interface ytype {
   a: I1;
   b: I1;
   c: I1;
}



 export interface I2 {
        y: ytype;
        z: any;
    }

Sie können es folgendermaßen importieren:

   import {I1, I2, ytype} from 'your_file'
JCorriveau
quelle
Alles ist in Ordnung, aber wie bereits erwähnt - die Schnittstellen I1 und I2 stammen aus einer externen Bibliothek und sind in der Datei d.ts für diese Bibliothek definiert. Daher wäre diese ytype-Schnittstelle eine Codeduplizierung und müsste ständig aktualisiert werden.
Kuba Jagoda