Direkt zum Hauptinhalt springen
eLearner.app
Modul 2 · Lektion 2 von 24/14 im Kurs~15 min
Lektionen des Moduls (2/2)

Unions und Type Narrowing

In der Praxis haben Variablen und API-Antworten nicht immer einen einzigen festen Typ. TypeScript bietet Union-Typen (Union Types) zur Verwaltung dieser Variabilität und das Einschränken von Typen (Type Narrowing), um zur Laufzeit sicher mit ihnen zu arbeiten.


Union-Typen (Union Types)

Ein Union-Typ erlaubt es einer Variablen, Werte verschiedener Typen zu akzeptieren. Er wird durch das vertikale Strichsymbol (|) ausgedrückt:

TS
let result: number | string;
result = 42; // Valido
result = 'Errore 404'; // Valido

Wenn wir jedoch mit einem Union-Typ arbeiten, können wir Methoden, die nur zu einem der Typen gehören, nicht direkt aufrufen (z. B. können wir .toUpperCase() nicht ausführen, wenn die Variable auch eine number sein kann). Wir müssen zuerst den Typ einschränken.


Einschränken von Typen (Type Narrowing)

Unter Type Narrowing versteht man den Prozess, bei dem TypeScript Kontrollflussstrukturen (wie if oder switch) analysiert, um zur Laufzeit auf einen spezifischeren Typ für eine Variable zu schließen.

Es gibt verschiedene Möglichkeiten, das Einschränken durchzuführen:

1. Der Operator typeof

Ideal zur Unterscheidung primitiver Typen:

TS
function printLength(value: string | number) {
  if (typeof value === 'string') {
    // Qui TypeScript sa che 'value' è una stringa
    console.log(value.length);
  } else {
    // Qui TypeScript sa che 'value' è un numero
    console.log(value.toFixed(2));
  }
}

2. Der Operator in

Wird verwendet, um das Vorhandensein einer bestimmten Eigenschaft in einem Objekt zu überprüfen:

TS
interface Fish {
  swim: () => void;
}
interface Bird {
  fly: () => void;
}

function move(animal: Fish | Bird) {
  if ('swim' in animal) {
    animal.swim(); // Narrowing a Fish
  } else {
    animal.fly(); // Narrowing a Bird
  }
}

Diskriminierte Unions (Discriminated Unions)

Das Muster der diskriminierten Unions besteht darin, Objekte zu erstellen, die eine gemeinsame Eigenschaft mit einem eindeutigen Literalwert (dem sogenannten Diskriminator) teilen. TypeScript erkennt diesen Diskriminator und führt innerhalb von bedingten Blöcken automatisch ein Type Narrowing durch.

TS
interface SuccessResponse {
  status: 'success'; // Discriminatore letterale
  data: string;
}

interface ErrorResponse {
  status: 'error'; // Discriminatore letterale
  errorMessage: string;
}

type ApiResponse = SuccessResponse | ErrorResponse;

function handleResponse(response: ApiResponse) {
  if (response.status === 'success') {
    console.log('Dati ricevuti:', response.data);
  } else {
    console.error('Si è verificato un errore:', response.errorMessage);
  }
}

Probier es aus

Esercizio 1: Union-Typen

Übung#ts.m2.l2.e1
Versuche: 0Wird geladen…

Deklariere eine Variable namens id, die entweder eine Zahl oder ein String sein kann. Initialisiere sie zuerst mit der Zahl 101 und weise ihr dann den String-Wert 'USER-101' zu.

Editor wird geladen…
Hinweis anzeigen

Verwende den Operator | zur Verbindung von number und string bei der Deklaration der let-Variable.

Lösung nach 3 Versuchen verfügbar

Esercizio 2: Einfaches Type Narrowing

Übung#ts.m2.l2.e2
Versuche: 0Wird geladen…

Erstelle eine Funktion namens formatInput, die einen Parameter input vom Typ String oder Zahl akzeptiert. Wenn input ein String ist, gib den in Großbuchstaben umgewandelten String zurück. Wenn es eine Zahl ist, gib den mit 2 multiplizierten Wert zurück. Spezifiziere die Typen explizit.

Editor wird geladen…
Hinweis anzeigen

Verwende typeof input === 'string' innerhalb eines if-Blocks, um das Verhalten zu steuern.

Lösung nach 3 Versuchen verfügbar

Esercizio 3: Narrowing mit 'in'

Übung#ts.m2.l2.e3
Versuche: 0Wird geladen…

Schreibe gegeben den beiden Interfaces Car (mit der Methode drive) und Boat (mit der Methode sail) eine Funktion namens moveVehicle, die einen Parameter vehicle vom Typ Car oder Boat akzeptiert. Wenn vehicle die Eigenschaft drive besitzt, führe die Methode drive() aus. Andernfalls führe die Methode sail() aus.

Editor wird geladen…
Hinweis anzeigen

Verwende den Operator in der Form 'drive' in vehicle, um das Interface einzuschränken.

Lösung nach 3 Versuchen verfügbar

Esercizio 4: Diskriminierte Union Shape

Übung#ts.m2.l2.e4
Versuche: 0Wird geladen…

Definiere einen Typ Shape, der die Union zweier Typen ist: Circle und Square. Circle hat eine Eigenschaft kind mit dem Wert 'circle' (Literalwert) und einen radius (Zahl). Square hat eine Eigenschaft kind mit dem Wert 'square' (Literalwert) und ein side (Zahl). Schreibe dann eine Funktion getArea, die shape vom Typ Shape akzeptiert und die Fläche als Zahl zurückgibt (für den Kreis Math.PI * radius * radius, für das Quadrat side * side).

Editor wird geladen…
Hinweis anzeigen

Verwende shape.kind === 'circle' innerhalb von getArea, um den Typ zu diskriminieren und die korrekte Fläche zu berechnen.

Lösung nach 3 Versuchen verfügbar