TypeScript ist ein leistungsstarkes Instrument zum Erstellen skalierbarer JavaScript -Anwendungen und ist fast zum Standard für große Web -JavaScript -Projekte geworden. Für Neulinge hat TypeScript jedoch auch einige schwierige Dinge, von denen eine zwischen Gewerkschaftstypen unterscheidet.
Betrachten Sie den folgenden Code:
Schnittstellenkatze { Gewicht: Zahl; Schnurrhaare: Nummer; } Schnittstellenhund { Gewicht: Zahl; freundlich: boolean; } Lass Animal: Hund | Katze;
Viele Entwickler werden überrascht sein, dass beim Zugriff auf animal
nur weight
gültig ist, während whiskers
und friendly
Attribute ungültig sind. Dieser Artikel erläutert die Gründe.
Bevor wir uns darauf eintauchen, überprüfen wir schnell strukturelle und nominelle Typen, um die Unterscheidung von TypeScript zwischen Gewerkschaftstypen zu verstehen.
Der beste Weg, um Strukturarten zu verstehen, besteht darin, sie mit nominalen Typen zu vergleichen. Die meisten typisierten Sprachen, die Sie möglicherweise verwendet haben, sind nominell eingegeben. Zum Beispiel C# Code (Java oder C ähnlich):
Klasse foo { public int x; } Klasse bla { public int x; }
Auch wenn Foo
und Blah
genau die gleiche Struktur haben, können sie keine Werte zuweisen. Der folgende Code:
Bla b = neu foo ();
Der folgende Fehler wird generiert:
<code>无法隐式转换类型“Foo”为“Blah”</code>
Die Struktur dieser Klassen spielt keine Rolle. Eine Variable des Typs Foo
kann nur einer Instanz Foo
-Klasse (oder ihrer Unterklasse) zugewiesen werden.
Typscript übernimmt im Gegenteil Strukturtypen. TypeScript berücksichtigt sie kompatibel, wenn beide Typen die gleiche Struktur haben.
Daher funktioniert der folgende Code gut:
Klasse foo { x: number = 0; } Klasse bla { x: number = 0; } Sei f: foo = neu bla (); sei b: bla = neu foo ();
Lassen Sie uns dies weiter erklären. Angesichts des folgenden Code:
Klasse foo { x: number = 0; } lass f: foo;
f
ist eine Variable, die jedes Objekt enthalten kann, das die gleiche Struktur wie Foo
Klasse-Instanz ist, in diesem Fall, was eine x
Eigenschaft bedeutet, die eine Zahl darstellt. Dies bedeutet, dass selbst ein normales JavaScript -Objekt akzeptiert werden kann.
lass f: foo; f = { x: 0 };
Kehren wir zu Beginn dieses Artikels zum Code zurück:
Schnittstellenkatze { Gewicht: Zahl; Schnurrhaare: Nummer; } Schnittstellenhund { Gewicht: Zahl; freundlich: boolean; }
Wir wissen:
Tiertiere: Hund;
Machen Sie animal
ein Objekt mit der gleichen Struktur wie die Dog
. Was bedeutet der folgende Code?
Lass Animal: Hund | Katze;
Dadurch definiert der animal
jedes Objekt, das der Dog
entspricht, oder jedes Objekt, das der Cat
entspricht.
Warum ermöglicht es uns animal
nur noch, auf weight
zugreifen zu können? Einfach ausgedrückt, dass TypeScript nicht weiß, welcher Typ es ist. TypeScript weiß animal
Dog
oder Cat
sein muss, aber es kann sich auch geben. Wenn wir auf das friendly
Eigentum zugreifen dürfen, aber im Fall animal
tatsächlich Cat
und kein Dog
ist, kann dies zu einem Laufzeitfehler führen. Gleiches gilt für whiskers
.
Gewerkschaftstyp ist eine Vereinigung gültiger Werte, nicht eine Vereinigung von Attributen. Entwickler schreiben oft einen solchen Code:
Lass Animal: Hund | Katze;
Und erwarten Sie, dass animal
eine Vereinigung von Dog
und Cat
hat. Aber das ist ein weiterer Fehler. Dies gibt an, animal
einen Wert hat, der mit einem Gelenk mit gültigen Dog
und gültigen Cat
übereinstimmt. Mit Typenschrift können Sie jedoch nur auf Eigenschaften zugreifen, die es gibt . Derzeit bedeutet dies alle Arten von Eigenschaften in der Gewerkschaft.
Jetzt haben wir:
Lass Animal: Hund | Katze;
Wie können wir ihn dann als animal
Dog
Dog
und auf Eigenschaften der Dog
zugreifen und sie auch mit Cat
umgehen? Derzeit können wir den in
verwenden. Dies ist ein alter JavaScript -Operator, den Sie möglicherweise nicht sehr oft sehen, was es uns ermöglicht, zu testen, ob eine Eigenschaft in einem Objekt existiert. Zum Beispiel:
sei o = {a: 12}; "a" in o; // wahr "x" in o; // falsch
Es stellt sich heraus, dass das Typenkript tief in
den Operator integriert ist. Mal sehen, wie man verwendet:
let Animal: Hund | cat = {} wie jeder andere; if ("freundlich" im Tier) { console.log (Animal.freund); } anders { console.log (Animal.whisker); }
Dieser Code erzeugt keine Fehler. In dem if
-Block weiß TypeScript, dass es eine friendly
Immobilie gibt, wandelt sich also animal
in Dog
um. Innerhalb des else
-Blocks behandelt TypeScript in ähnlicher Weise animal
als Cat
. Sie können dies sogar im Code -Editor anzeigen, indem Sie Ihre Maus über ein animal
in diesen Blöcken schweben.
Sie könnten erwarten, dass der Blog -Beitrag hier endet, aber leider ist die Eingrenzung des Gewerkschaftstyps sehr begrenzt, wenn das Attribut existiert. Es funktioniert gut für unsere einfachen Dog
und Cat
, aber wenn wir mehr Typen und mehr Überlappungen zwischen diesen Typen haben, können die Dinge leicht komplexer und zerbrechlicher werden.
Hier ist die Unterscheidung des Gewerkschaftstyps nützlich. Wir werden alles von früher behalten, einfach eine Eigenschaft zu jedem Typ hinzufügen, dessen einziger Zweck darin besteht, diese Typen zu unterscheiden (oder zu differenzieren "):
Schnittstellenkatze { Gewicht: Zahl; Schnurrhaare: Nummer; Animal_type: "Katze"; } Schnittstellenhund { Gewicht: Zahl; freundlich: boolean; Animal_type: "Hund"; }
Beachten Sie das Attribut ANIMAL_TYPE
für beide Typen. Verwechseln Sie es nicht mit zwei verschiedenen Werten. ANIMAL_TYPE: "CAT";
Jetzt ist unsere Inspektion zuverlässiger geworden:
let Animal: Hund | cat = {} wie jeder andere; if (Animal.Animal_type === "Hund") { console.log (Animal.freund); } anders { console.log (Animal.whisker); }
Diese Überprüfung ist narrensicher, vorausgesetzt, jeder an der Gewerkschaft beteiligte Typ hat einen anderen Wert des Attributs von ANIMAL_TYPE
.
Der einzige Nachteil ist, dass Sie sich jetzt mit einer neuen Immobilie befassen müssen. Jedes Mal, wenn eine Instanz von Dog
oder Cat
erstellt wird, müssen Sie den einzigartigen korrekten Wert für ANIMAL_TYPE
bereitstellen. Aber mach dir keine Sorgen um das Vergessen, denn Typscript wird dich daran erinnern. ?
Wenn Sie mehr erfahren möchten, empfehle ich das Lesen der Typscript -Dokumentation zur Verengung des Typs. Dies gibt uns einen detaillierteren Blick auf das, was wir hier diskutieren. In diesem Link gibt es einen Abschnitt zu Typbehauptungen. Mit diesen können Sie Ihre eigenen benutzerdefinierten Überprüfungen definieren, um die Typen einzugrenzen, ohne Diskriminatoren zu verwenden oder sich auf das in
zu verlassen.
Zu Beginn dieses Artikels sagte ich im folgenden Beispiel, warum weight
die einzige zugängliche Eigenschaft ist:
Schnittstellenkatze { Gewicht: Zahl; Schnurrhaare: Nummer; } Schnittstellenhund { Gewicht: Zahl; freundlich: boolean; } Lass Animal: Hund | Katze;
Was wir gelernt haben, ist, dass Typenkript nur weiß animal
Dog
Cat
, aber nicht beides sein kann. Daher können wir nur weight
bekommen, was die einzige öffentliche Eigenschaft zwischen den beiden ist.
Das Konzept der Unterscheidung von Gewerkschaftstypen ist die Art und Weise, wie Typenkript diese Objekte unterscheidet, und dieser Ansatz ist selbst für größere Sammlungen von Objekten sehr skalierbar. Daher müssen wir eine neue ANIMAL_TYPE
-Eigenschaft für beide Typen erstellen, die einen einzigen wörtlichen Wert enthält, den wir zum Überprüfen verwenden können. Dies ist natürlich eine andere Sache, die verfolgt werden muss, aber es führt auch zuverlässigere Ergebnisse - genau das ist das, was wir von TypeScript in erster Linie wollen.
Das obige ist der detaillierte Inhalt vonEntmystifizierende typecript diskriminierte Gewerkschaften. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!