Direct naar de hoofdinhoud
Module 2 · Les 2 van 24/14 in de cursus~15 min
Modulelessen (2/2)

Vakbonden en vernauwing

In de echte wereld hebben variabelen en API-reacties niet altijd één vast type. TypeScript biedt Union Types om met variabiliteit om te gaan, en Type Narrowing om er tijdens runtime veilig mee te kunnen werken.


Union-typen

Met een samenvoegingstype kan een variabele waarden van verschillende typen accepteren. Het wordt uitgedrukt met behulp van het verticale balksymbool (|):

TS
let result: number | string;
result = 42; // Valid
result = 'Error 404'; // Valid

Wanneer we echter met een samenvoegingstype werken, kunnen we methoden die slechts tot één van de typen behoren niet rechtstreeks aanroepen (we kunnen bijvoorbeeld .toUpperCase() niet aanroepen als de variabele ook een number kan zijn). We moeten eerst het type "versmallen".


Type vernauwing

Typevernauwing is het proces waarbij TypeScript besturingsstroomstructuren (zoals if of switch) analyseert om een ​​specifieker type voor een variabele tijdens runtime af te leiden.

Er zijn verschillende manieren om vernauwing uit te voeren:

1. De typeof-operator

Ideaal voor het onderscheiden van primitieve typen:

TS
function printLength(value: string | number) {
  if (typeof value === 'string') {
    // TypeScript knows 'value' is a string here
    console.log(value.length);
  } else {
    // TypeScript knows 'value' is a number here
    console.log(value.toFixed(2));
  }
}

2. De in-operator

Wordt gebruikt om te controleren of een specifieke eigenschap voor een object bestaat:

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

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

Gediscrimineerde vakbonden

Het patroon Gediscrimineerde Unies bestaat uit het maken van objecten die een gemeenschappelijke eigenschap delen met een unieke letterlijke waarde (een zogenaamde discriminator). TypeScript herkent deze discriminator en beperkt automatisch het type binnen voorwaardelijke blokken.

TS
interface SuccessResponse {
  status: 'success'; // Literal discriminator
  data: string;
}

interface ErrorResponse {
  status: 'error'; // Literal discriminator
  errorMessage: string;
}

type ApiResponse = SuccessResponse | ErrorResponse;

function handleResponse(response: ApiResponse) {
  if (response.status === 'success') {
    console.log('Data received:', response.data);
  } else {
    console.error('An error occurred:', response.errorMessage);
  }
}

Probeer het zelf

Oefening 1: Union-typen

Oefening#ts.m2.l2.e1
Pogingen: 0Laden…

Declareer een variabele met de naam id die een getal of een tekenreeks kan zijn. Initialiseer het eerst met het nummer 101 en wijs vervolgens de stringwaarde 'USER-101' toe.

Editor laden…
Toon hint

Gebruik de | operator om nummer en string samen te voegen in de let-variabeledeclaratie.

Oplossing beschikbaar na 3 pogingen

Oefening 2: Basistypevernauwing

Oefening#ts.m2.l2.e2
Pogingen: 0Laden…

Maak een functie met de naam formatInput die een parameterinvoer van het type string of number accepteert. Als de invoer een tekenreeks is, retourneert u de invoer geconverteerd naar hoofdletters. Als het een getal is, retourneert u de invoer vermenigvuldigd met 2. Geef typen expliciet op.

Editor laden…
Toon hint

Gebruik typeof input === 'string' binnen een if-blok om het gedrag te vertakken.

Oplossing beschikbaar na 3 pogingen

Oefening 3: Versmallen met 'in'

Oefening#ts.m2.l2.e3
Pogingen: 0Laden…

Gegeven de twee interfaces Auto (met methode rijden) en Boot (met methode varen), schrijft u een functie met de naam moveVehicle die een parameter voertuig van het type Auto of Boot accepteert. Als het voertuig de eigenschap drive heeft, voer dan de methode drive() uit. Voer anders de methode sail() uit.

Editor laden…
Toon hint

Gebruik de operator in in de vorm 'rijden' in voertuig om de interface te verkleinen.

Oplossing beschikbaar na 3 pogingen

Oefening 4: Gedifferentieerde Unievorm

Oefening#ts.m2.l2.e4
Pogingen: 0Laden…

Definieer een type Vorm dat de vereniging is van twee typen: Cirkel en Vierkant. Circle heeft een soort eigenschap ingesteld op 'circle' (letterlijke waarde) en een straal (getal). Vierkant heeft een soort eigenschap ingesteld op 'vierkant' (letterlijke waarde) en een zijde (getal). Schrijf vervolgens een functie getArea die de vorm van het type Shape accepteert en de oppervlakte als een getal retourneert (voor cirkel Math.PI * straal * straal, voor vierkante zijde * zijde).

Editor laden…
Toon hint

Gebruik shape.kind === 'circle' binnen getArea om het type te onderscheiden en de juiste oppervlakte te berekenen.

Oplossing beschikbaar na 3 pogingen