TypeScript für Anfänger, Teil 3 Schnittstellen

Wir haben diese Serie mit einem einführenden Tutorial begonnen, das Sie mit den verschiedenen TypeScript-Funktionen vertraut machte. Außerdem haben Sie die Installation von TypeScript kennengelernt und einige IDEs vorgeschlagen, mit denen Sie eigenen TypeScript-Code schreiben und kompilieren können. 

Im zweiten Lernprogramm haben wir verschiedene in TypeScript verfügbare Datentypen behandelt und wie Sie mithilfe dieser Datentypen viele Fehler vermeiden können. Zuweisen eines Datentyps wie a Schnur zu einer bestimmten Variablen sagt TypeScript, dass Sie nur eine Zeichenfolge zuweisen möchten. Aufgrund dieser Informationen kann TypeScript Sie später darauf hinweisen, wenn Sie versuchen, eine Operation auszuführen, die nicht für Zeichenfolgen ausgeführt werden soll.

In diesem Lernprogramm erfahren Sie mehr über Schnittstellen in TypeScript. Mit Schnittstellen können Sie einen Schritt weitergehen und die Struktur oder den Typ komplexerer Objekte in Ihrem Code definieren. Diese Objekte müssen ebenso wie einfache Variablentypen einem von Ihnen erstellten Satz von Regeln folgen. Auf diese Weise können Sie Code sicherer schreiben und haben weniger Fehler.

Erstellen unserer ersten Schnittstelle

Angenommen, Sie haben ein Seeobjekt in Ihrem Code, und Sie speichern damit Informationen zu einigen der größten Seen der Welt. Dieses Seeobjekt hat Eigenschaften wie den Namen des Sees, seine Fläche, Länge, Tiefe und die Länder, in denen der See existiert.

Die Namen der Seen werden als Zeichenfolge gespeichert. Die Länge dieser Seen wird in Kilometern angegeben, und die Flächen werden in Quadratkilometern angegeben, aber beide dieser Eigenschaften werden als Zahlen gespeichert. Die Tiefen der Seen werden in Metern liegen und dies könnte auch ein Schwimmer sein. 

Da all diese Seen sehr groß sind, sind ihre Küsten im Allgemeinen nicht auf ein Land beschränkt. Wir werden eine Reihe von Strings verwenden, um die Namen aller Länder an der Küste eines bestimmten Sees zu speichern. Mit einem Boolean kann angegeben werden, ob der See Salzwasser oder Süßwasser ist. Der folgende Codeausschnitt erstellt eine Schnittstelle für unser Seeobjekt.

Schnittstelle Lakes Name: String, Bereich: Nummer, Länge: Nummer, Tiefe: Nummer, isFreshwater: Boolean, Länder: String []

Das Seen Interface enthält den Typ jeder Eigenschaft, die wir beim Erstellen unserer Seeobjekte verwenden werden. Wenn Sie jetzt versuchen, einer dieser Eigenschaften unterschiedliche Wertetypen zuzuweisen, wird eine Fehlermeldung angezeigt. Hier ist ein Beispiel, das Informationen über unseren ersten See speichert.

let firstLake: Lakes = name: 'Kaspian Sea', Länge: 1199, Tiefe: 1025, Fläche: 371000, isFreshwater: false, Länder: ['Kasachstan', 'Russland', 'Turkmenistan', 'Aserbaidschan', 'Iran' ']

Wie Sie sehen, spielt die Reihenfolge, in der Sie diesen Eigenschaften einen Wert zuweisen, keine Rolle. Sie können jedoch keinen Wert auslassen. Sie müssen jeder Eigenschaft einen Wert zuweisen, um Fehler beim Kompilieren des Codes zu vermeiden. 

Auf diese Weise stellt TypeScript sicher, dass Sie nicht versehentlich die erforderlichen Werte verpasst haben. Hier ist ein Beispiel, bei dem wir vergessen haben, den Wert von zuzuweisen Tiefe Eigentum für einen See.

let secondLake: Lakes = name: 'Superior', Länge: 616, Gebiet: 82100, isFreshwater: true, Länder: ['Canada', 'United States']

Der Screenshot unten zeigt die Fehlermeldung in Visual Studio Code, nachdem wir vergessen haben, das anzugeben Tiefe. Wie Sie sehen, weist der Fehler eindeutig darauf hin, dass wir das vermissen Tiefe Eigentum für unser Seeobjekt.

Schnittstelleneigenschaften optional machen

Manchmal benötigen Sie eine Eigenschaft nur für bestimmte Objekte. Angenommen, Sie möchten eine Eigenschaft hinzufügen, um die Monate anzugeben, in denen ein See gefroren ist. Wenn Sie die Eigenschaft, wie bisher, direkt zur Schnittstelle hinzufügen, erhalten Sie einen Fehler für andere Seen, die nicht einfrieren und daher keine haben gefroren Eigentum. Wenn Sie diese Eigenschaft zu Seen hinzufügen, die eingefroren sind, aber nicht in der Schnittstellendeklaration enthalten sind, wird ebenfalls ein Fehler angezeigt.

In solchen Fällen können Sie ein Fragezeichen hinzufügen (?) hinter dem Namen einer Eigenschaft, um sie in der Schnittstellendeklaration als optional festzulegen. Auf diese Weise erhalten Sie weder für fehlende noch für unbekannte Eigenschaften einen Fehler. Das folgende Beispiel sollte es deutlich machen.

interface Lakes Name: String, Bereich: Nummer, Länge: Nummer, Tiefe: Number, isFreshwater: Boolean, Länder: String [], eingefroren ?: String [] let secondLake: Lakes = Name: 'Superior', Tiefe: 406.3, Länge: 616, Gebiet: 82100, isFreshwater: wahr, Länder: ['Canada', 'United States'] let ThirdLake: Lakes = Name: 'Baikal', Tiefe: 1637, Länge: 636, Fläche: 31500 , isFreshwater: wahr, Länder: ['Russland'], eingefroren: ['Januar', 'Februar', 'März', 'April', 'Mai']

Index-Signaturen verwenden

Optionale Eigenschaften sind nützlich, wenn einige Ihrer Objekte sie verwenden. Was wäre aber, wenn jeder See seine eigenen einzigartigen Eigenschaften hätte, wie wirtschaftliche Aktivitäten, die Ansammlung verschiedener Arten von Flora und Fauna in diesem See oder die Siedlungen rund um den See? Es ist nicht ideal, so viele verschiedene Eigenschaften in die Deklaration der Schnittstelle selbst aufzunehmen und optional zu machen.

Als Lösung können Sie mit TypeScript mithilfe von Indexsignaturen zusätzliche Eigenschaften für bestimmte Objekte hinzufügen. Durch Hinzufügen einer Indexsignatur zur Schnittstellendeklaration können Sie eine beliebige Anzahl von Eigenschaften für verschiedene Objekte angeben, die Sie erstellen. Sie müssen die folgenden Änderungen an der Schnittstelle vornehmen. 

In diesem Beispiel habe ich eine Indexsignatur verwendet, um Informationen zu verschiedenen Siedlungen rund um die Seen hinzuzufügen. Da jeder See seine eigenen Siedlungen haben wird, wäre die Verwendung optionaler Eigenschaften keine gute Idee gewesen.

Schnittstelle Lakes Name: Zeichenfolge, Fläche: Anzahl, Länge: Anzahl, Tiefe: Anzahl, isFreshwater: Boolean, Länder: Zeichenfolge [], eingefroren ?: Zeichenfolge [], [ExtraProp: Zeichenfolge]: beliebig let 4thLake: Lakes =  Name: 'Tanganyika', Tiefe: 1470, Länge: 676, Fläche: 32600, isFreshwater: true, Länder: ['Burundi', 'Tanzania', 'Sambia', 'Kongo'], Kigoma: 'Tanzania', Kalemie: 'Kongo', bujumbura: 'Burundi'

Angenommen, Sie erstellen ein Spiel mit verschiedenen Arten von Gegnern. Alle diese Feinde haben einige gemeinsame Eigenschaften wie ihre Größe und ihre Gesundheit. Diese Eigenschaften können direkt in die Schnittstellendeklaration aufgenommen werden. Wenn jede Kategorie dieser Feinde über einen einzigartigen Satz von Waffen verfügt, können diese Waffen mithilfe einer Indexsignatur aufgenommen werden.

Schreibgeschützte Eigenschaften

Wenn Sie mit verschiedenen Objekten arbeiten, müssen Sie möglicherweise mit Eigenschaften arbeiten, die nur beim Erstellen des Objekts geändert werden sollten. Sie können diese Eigenschaften als kennzeichnen schreibgeschützt in der Schnittstellendeklaration. Dies ist ähnlich wie bei der Verwendung von const Stichwort, aber const soll mit Variablen verwendet werden, während schreibgeschützt ist für Eigenschaften gedacht.

Mit TypeScript können Sie auch Arrays schreibgeschützt machen, indem Sie verwenden ReadonlyArray. Durch das Erstellen eines schreibgeschützten Arrays werden alle Mutationsmethoden daraus entfernt. Dadurch wird sichergestellt, dass Sie den Wert einzelner Elemente später nicht ändern können. Hier ein Beispiel für die Verwendung von schreibgeschützten Eigenschaften und Arrays in Schnittstellendeklarationen.

Schnittstelle Feind Readonly Größe: Anzahl, Gesundheit: Anzahl, Bereich: Anzahl, Readonly Schaden: Anzahl Tank lassen: Feind = Größe: 50, Gesundheit: 100, Reichweite: 60, Schaden: 12 // Dies ist ein Okay-Tank. Gesundheit = 95; // Fehler, weil "Schaden" schreibgeschützt ist. tank.damage = 10;

Funktionen und Schnittstellen

Sie können Schnittstellen auch verwenden, um einen Funktionstyp zu beschreiben. Dazu müssen Sie der Funktion eine Anrufsignatur mit ihrer Parameterliste und ihrem Rückgabetyp zuweisen. Außerdem müssen Sie für jeden Parameter einen Namen und einen Typ angeben. Hier ist ein Beispiel:

Schnittstelle EnemyHit (Name: Feind, SchadenDon: Nummer): Nummer;  let tankHit: EnemyHit = Funktion (tankName: Feind, damageDone: number) tankName.health - = damageDone; return tankName.health; 

Im obigen Code haben wir eine Funktionsschnittstelle deklariert und verwendet, um eine Funktion zu definieren, die den an einem Panzer erlittenen Schaden von seiner Gesundheit subtrahiert. Wie Sie sehen, müssen Sie nicht für Parameter in der Schnittstellendeklaration und für die Definition des zu verwendenden Codes denselben Namen verwenden.

Abschließende Gedanken

In diesem Lernprogramm wurden die Schnittstellen und deren Verwendung beschrieben, um sicherzustellen, dass Sie stabileren Code schreiben. Sie sollten jetzt in der Lage sein, eigene Schnittstellen mit optionalen und schreibgeschützten Eigenschaften zu erstellen. 

Sie haben auch gelernt, wie Sie Indexsignaturen verwenden, um einem Objekt eine Reihe anderer Eigenschaften hinzuzufügen, die nicht in der Schnittstellendeklaration enthalten sind. In diesem Lernprogramm sollten Sie mit den Schnittstellen in TypeScript beginnen. Weitere Informationen zu diesem Thema finden Sie in der offiziellen Dokumentation.

Im nächsten Tutorial erfahren Sie mehr über Klassen in TypeScript. Wenn Sie Fragen zu Schnittstellen haben, lassen Sie es mich in den Kommentaren wissen.