TypeScript spezielle Typen: never, void, unknown, any
TypeScript hat vier spezielle Typen: never, void, unknown und any.
Sie spielen eine wichtige Rolle im Typsystem. Ihre Unterschiede zu verstehen ist entscheidend für das Schreiben typsicheren Codes.
SVG-Diagramm: Vergleich spezieller Typen
Warum spezielle Typen benötigt werden
Das Typsystem von TypeScript ist sehr leistungsfähig. Zusätzlich zu regulären Typen bietet es vier spezielle Typen, um bestimmte Szenarien zu behandeln.
Das Verständnis der Unterschiede zwischen diesen vier speziellen Typen hilft uns, sichereren und genaueren typisierten Code zu schreiben.
Konzepterklärung:never, void, unknown und any sind spezielle Typen von TypeScript, jeder mit unterschiedlicher Bedeutung und unterschiedlichen Anwendungsfällen.
Der never-Typ
never steht für einen Typ, der niemals zurückkehrt. Er wird normalerweise für Funktionen verwendet, die Ausnahmen auslösen oder unendlich oft ausgeführt werden.
Beispiel
// Die Funktion kehrt niemals normal zurück; sie löst immer einen Fehler aus
function throwError(message: string): never {
throw new Error(message);
}
// Funktion mit einer Endlosschleife
// Die Funktion kehrt nie zurück; das Programm läuft weiter
function infiniteLoop(): never {
while (true) {
console.log("Running...");
}
}
// never ist ein Untertyp aller Typen
// Das bedeutet, never kann jedem Typ zugewiesen werden
var neverValue: never;
var num: number = neverValue; // Korrekt: never ist ein Subtyp von number
console.log("never einer number zugewiesen: " + num);
Ausgabe:
never 赋值给 number: undefined
Wichtig:never ist ein Subtyp aller Typen, was bedeutet, dass never jedem Typ zugewiesen werden kann, aber kein Typ kann never zugewiesen werden (außer never selbst).
Der void-Typ
void bedeutet, dass es keinen Rückgabewert gibt, und wird normalerweise verwendet, um Funktionen zu deklarieren, die keine return-Anweisung haben.
Beispiel
// Die Funktion hat nach der Ausführung keinen Rückgabewert
function logMessage(message: string): void {
console.log("Protokoll: " + message);
// Keine return-Anweisung oder return undefined
}
logMessage("Hallo");
// void-Variable (selten verwendet)
// Kann nur undefined zugewiesen werden
var empty: void = undefined;
console.log("void-Variable: " + empty);
Ausgabe:
日志: Hello void 变量: undefined
Erklärung:void ist tatsächlich sehr ähnlich zu undefined und wird hauptsächlich für die Deklaration des Rückgabetyps von Funktionen verwendet, um anzuzeigen, dass die Funktion keinen Rückgabewert hat.
Der unknown-Typ
unknown ist ein typsicheres any. Wenn man unknown verwendet, muss man vor der Verwendung eine Typprüfung durchführen.
Beispiel
// Dies ist ein "sicheres" any
var value: unknown = "hello";
value = 42;
value = true;
// Ein unknown-Typ kann nicht direkt anderen Typen zugewiesen werden
// Wenn Sie die Kommentierung der nächsten Zeile aufheben, meldet der Compiler einen Fehler
// var str: string = value;
// Es kann erst nach der Typprüfung zugewiesen werden
if (typeof value === "string") {
// TypeScript weiß, dass value vom Typ string ist
var str: string = value;
console.log("Stringlänge: " + str.length);
}
Ausgabe:
字符串长度: 5
Sicherheit:unknown erzwingt eine Typprüfung vor der Verwendung, was die Typsicherheit schützt. Bei der Verarbeitung von Daten aus unbekannten Quellen sollten Sie unknown anstelle von any verwenden.
Der any-Typ
any umgeht die Typprüfung vollständig und kann jeden Typ annehmen. Es ist der unsicherste Typ in TypeScript.
Beispiel
// Umgeht die Typprüfung vollständig
var anything: any = "hello";
anything = 42;
anything = true;
// any kann jedem Typ zugewiesen werden
// Dies verletzt die Typsicherheit
var str: string = anything;
var num: number = anything;
console.log("String: " + str);
console.log("Number: " + num);
// Ein Objekt vom Typ any kann jede Methode aufrufen
// Der Compiler meldet keinen Fehler, aber es kann zur Laufzeit fehlschlagen
var obj: any = {};
obj.foo(); // Es wird kein Fehler gemeldet, aber die foo-Methode existiert tatsächlich nicht
obj.bar = "value";
Warnung:Der any-Typ umgeht die Typprüfung von TypeScript vollständig und sollte so weit wie möglich vermieden werden. Wenn er verwendet werden muss, stelle sicher, dass der Typ des Werts korrekt ist.
Vergleich von any vs. unknown
Sowohl any als auch unknown können jeden Typ akzeptieren, aber ihre Sicherheit ist völlig unterschiedlich.
| Merkmal | any | unknown |
|---|---|---|
| Akzeptiert jeden Typ | ✓ Ja | ✓ Ja |
| Direkt anderen Typen zuweisbar | ✓ Ja | ✗ Nein (erfordert Prüfung) |
| Methoden direkt aufrufen | ✓ Ja | ✗ Nein (erfordert Prüfung) |
| Typsicherheit | ✗ Keine | ✓ Ja |
Empfehlung:Bei der Verarbeitung von Daten unbekannter Typen verwenden Sie lieber unknown statt any, da dies die Typprüfung erzwingt.
never vs void
Sowohl never als auch void werden für Rückgabetypen von Funktionen verwendet, aber ihre Bedeutungen sind völlig unterschiedlich.
| Merkmal | never | void |
|---|---|---|
| Bedeutung | Kehrt nie zurück | Kein Rückgabewert |
| Wird für Funktionen verwendet | Ausnahmen auslösen / Endlosschleifen | Gewöhnliche Funktionen ohne Rückgabewert |
| Anderen Typen zuweisbar | ✓ Ja (Subtyp) | Nur void/any zuweisbar |
Hauptunterschied:never bedeutet, dass die Funktion niemals normal zurückkehrt (entweder löst sie eine Ausnahme aus oder gerät in eine Endlosschleife); void bedeutet, dass die Funktion normal ausgeführt wird, aber keinen Rückgabewert hat.
Praktische Anwendung: Vollständigkeitsprüfung
Eine wichtige Verwendung des never-Typs besteht darin, Vollständigkeitsprüfungen durchzuführen und dadurch sicherzustellen, dass alle möglichen Fälle behandelt wurden.
Beispiel
type Shape = { kind: "circle", radius: number }
| { kind: "square", side: number };
// Berechne die Fläche einer Form
function area(shape: Shape): number {
switch (shape.kind) {
case "circle":
return Math.PI * shape.radius ** 2;
case "square":
return shape.side ** 2;
default:
// Der Standardzweig sollte alle unerwarteten Fälle behandeln
// Wenn du einen neuen Shape-Typ hinzufügst, aber vergisst, ihn zu behandeln, meldet der Compiler einen Fehler
var _exhaustive: never = shape;
return _exhaustive;
}
}
var circle = { kind: "circle" as const, radius: 5 };
var square = { kind: "square" as const, side: 4 };
console.log("Kreisfläche: " + area(circle).toFixed(2));
console.log("Quadratfläche: " + area(square));
Ausgabe:
圆形面积: 78.54 正方形面积: 16
Vollständigkeitsprüfung:Dieses Muster stellt sicher, dass, wenn ein neuer Typzweig hinzugefügt wird und Sie vergessen, ihn im switch zu behandeln, der Compiler einen Fehler meldet, weil der neue Typ nicht never zugewiesen werden kann.
Hinweise
- never ist ein Untertyp:never kann jedem Typ zugewiesen werden, aber kein Typ kann never zugewiesen werden
- void vs undefined:In JavaScript sind void und undefined im Wesentlichen äquivalent
- unknown erfordert Prüfung:Bevor Sie einen Wert vom Typ unknown verwenden, müssen Sie eine Typprüfung durchführen.
- any vermeiden:Versuchen Sie, any nicht zu verwenden; bevorzugen Sie unknown.
Bewährte Verfahren:Typsicherheit von der höchsten zur niedrigsten: never > void > unknown > any. Verwenden Sie nach Möglichkeit sicherere Typen.
Zusammenfassung
Das Verständnis dieser vier speziellen Typen ist sehr wichtig für das Schreiben von hochwertigem TypeScript-Code.
- never:Kehrt nie zurück; wird für Vollständigkeitsprüfungen verwendet; ist ein Untertyp aller Typen.
- void:Kein Rückgabewert; wird für gewöhnliche Funktionen verwendet, die keinen Rückgabewert haben.
- unknown:Sicherer beliebiger Typ; vor der Verwendung muss eine Typprüfung durchgeführt werden.
- any:Umgeht alle Typüberprüfungen; sollte so weit wie möglich vermieden werden.
Weitere ErweiterungenEmpfehlungen:Bevorzugen Sie beim Schreiben von Code strengere Typen. Verwenden Sie unknown für unbekannte Daten, void für Funktionen ohne Rückgabewert und never, wenn vollständige Prüfungen erforderlich sind.