Lektionen des Moduls (1/2)
Type Guards
Das Einschränken von Typen (Type Narrowing) gehört zu den wichtigsten Konzepten in TypeScript. Häufig reichen jedoch Standard-Typwächter (Type Guards) wie typeof oder instanceof für komplexe benutzerdefinierte Objekte nicht aus. Hier kommen benutzerdefinierte Typwächter (Custom Type Guards) ins Spiel.
Standard-Typwächter
Beginnen wir mit einer Zusammenfassung, wie TypeScript Typen mithilfe der Standardoperatoren von JavaScript einschränkt:
function processInput(val: string | number) {
if (typeof val === 'string') {
// Qui 'val' è di tipo string
console.log(val.toUpperCase());
} else {
// Qui 'val' è di tipo number
console.log(val.toFixed(2));
}
}Benutzerdefinierte Typwächter (Operator is)
Um einen benutzerdefinierten Typwächter zu definieren, erstellen wir eine Funktion, die anstelle des standardmäßigen booleschen Rückgabetyps ein Typprädikat im Format parameterName is Type zurückgibt.
Die Funktion muss einen booleschen Wert (true oder false) zurückgeben. Wenn sie true zurückgibt, weiß TypeScript, dass der übergebene Parameter vom angegebenen Typ ist.
interface Cat {
name: string;
meow(): void;
}
interface Dog {
name: string;
bark(): void;
}
// Questa è una guardia di tipo personalizzata
function isCat(animal: Cat | Dog): animal is Cat {
return (animal as Cat).meow !== undefined;
}
function makeNoise(pet: Cat | Dog) {
if (isCat(pet)) {
// Qui TypeScript sa che 'pet' è un Cat
pet.meow();
} else {
// Qui TypeScript sa che 'pet' è un Dog
pet.bark();
}
}Sicherheit und Casting (as vs. Type Guards)
Typumwandlung (z. B. val as Cat) zwingt den Compiler, dem Entwickler ohne reale Laufzeitprüfung zu vertrauen. Wenn das Objekt zur Laufzeit nicht den Erwartungen entspricht, schlägt der Code stillschweigend fehl oder wirft Ausnahmen.
Benutzerdefinierte Typwächter ermöglichen stattdessen eine robuste und dynamische Prüfung zur Laufzeit und informieren den TypeScript-Compiler sicher und präzise über den tatsächlichen Typ der Variablen:
function processInput(input: unknown) {
// casting insicuro: potrebbe rompersi se input non ha il metodo split
// const str = input as string;
// console.log(str.split(' '));
// guardia sicura
if (isString(input)) {
console.log(input.split(' ')); // Sicuro al 100%!
}
}Probier es aus
Esercizio 1: Typwächter für Strings
Erstelle eine einfache Funktion namens isString, die als benutzerdefinierter Typwächter prüft, ob ein unknown-Wert ein String ist.
Hinweis anzeigen
Der Rückgabetyp der Funktion muss val is string sein, und du musst typeof verwenden, um zu prüfen, ob es sich um 'string' handelt.
Lösung nach 3 Versuchen verfügbar
Esercizio 2: Typwächter für Premium-Benutzer
Schreibe gegeben den Typen User und PremiumUser eine Typwächter-Funktion isPremiumUser(user: User): user is PremiumUser, die prüft, ob der Benutzer die Rolle 'premium' hat.
Hinweis anzeigen
Definiere die Signatur als function isPremiumUser(user: User): user is PremiumUser und vergleiche user.role mit 'premium'.
Lösung nach 3 Versuchen verfügbar
Esercizio 3: Überprüfung von benutzerdefiniertem Fehlerobjekt
Implementiere die Funktion isCustomError(err: unknown): err is CustomError, die prüft, ob ein unbekannter Wert ein nicht-null-Wert CustomError-Objekt ist, das den Schlüssel 'code' besitzt.
Hinweis anzeigen
Prüfe zuerst, ob typeof err gleich 'object' und nicht null ist, und verwende dann den Operator 'in', um das Vorhandensein der Eigenschaft 'code' zu prüfen.
Lösung nach 3 Versuchen verfügbar
Esercizio 4: Typwächter für Admin
Schreibe gegeben den beiden Interfaces User (mit der Eigenschaft role: string) und Admin (das User erweitert und eine Eigenschaft adminToken: string hat) eine Typwächter-Funktion namens isAdmin, die ein user-Objekt vom Typ User akzeptiert und ein Typprädikat user is Admin zurückgibt. Der Wächter muss prüfen, ob das role des Benutzers gleich 'admin' ist.
Hinweis anzeigen
Definiere die Signatur als function isAdmin(user: User): user is Admin und kontrolliere, ob user.role === 'admin'.
Lösung nach 3 Versuchen verfügbar