ProgrammatieFrontend ontwikkelaar

Hoe werkt het mechanisme van union types (samenvoegende types) in TypeScript? Waarom is het nodig, hoe werkt type narrowing en wat zijn de nuances van werken met union types?

Slaag voor sollicitatiegesprekken met de Hintsage AI-assistent

Antwoord.

Achtergrond:

Union types zijn geïntroduceerd in TypeScript om variabelen en parameters te beschrijven die waarden van verschillende types kunnen aannemen. Deze mogelijkheid heeft de flexibiliteit van type-afstemming aanzienlijk vergroot in vergelijking met klassieke talen.

Probleem:

In JavaScript hebben functies en variabelen vaak meerdere formaten (bijvoorbeeld een nummer of een string), wat veilige type-afstemming bemoeilijkt. Zonder union types moest men any gebruiken of de code dupliceren. Dit verhoogde het aantal fouten in productie en bemoeilijkte het werken in grote teams.

Oplossing:

Union types maken het mogelijk om een variabele te declareren die een van de verschillende types kan zijn, terwijl deze garandeert dat correcte operaties onderhanden worden na controle. Type narrowing is ook ondersteund, wat helpt voor de compiler om te "begrijpen" met wat hij te maken heeft.

Voorbeeld code:

function formatId(id: number | string): string { if (typeof id === 'string') { return id.toUpperCase(); } return id.toString(); }

Belangrijkste kenmerken:

  • Ze maken het mogelijk om expliciet de mogelijke types van variabelen en parameters aan te geven.
  • Ze werken samen met het type narrowing mechanisme door controles (bijvoorbeeld, typeof of in).
  • Ze compliceren het werken met objecten, waar dezelfde sleutel verschillende types kan hebben - er is zorgvuldige logica voor toegang nodig.

Vragen met een val.

Kan ik een union van objecten met verschillende eigenschappen schrijven en naar elke eigenschap verwezen zonder controle?

Nee. Union types laten alleen toegang toe tot de eigenschappen en methoden die in alle types aanwezig zijn. Voor toegang tot specifieke eigenschappen is type narrowing vereist.

Voorbeeld code:

type Fish = { swim: () => void; }; type Bird = { fly: () => void; }; function move(animal: Fish | Bird) { // animal.swim(); // Fout zonder narrowing if ('swim' in animal) { animal.swim(); // OK } }

Waarom zijn niet alle methoden beschikbaar voor de union type string | number?

TypeScript staat alleen toe wat in alle inbegrepen types aanwezig is in de union. Voor individuele methoden moet je eerst het echte type controleren.

Wat gebeurt er als ik het type in de union niet controleer en probeer een specifieke methode aan te roepen?

In dat geval ontstaat er een compilatiefout, omdat de aanwezigheid van de methode niet gegarandeerd is. Dit werkt alleen na controle van het specifieke type.

Typefouten en anti-patronen

  • Het overslaan van de typecontrole voordat je het gebruikt (kan toegangsfouten veroorzaken).
  • Het beschrijven van te brede union types (type veiligheid gaat verloren).
  • Onjuiste narrowing leidt tot onzichtbare fouten en not exhaustive checks.

Voorbeeld uit het leven

Negatief geval

Ik gaf een variabele het type string | number en zonder controle deed ik toUpperCase(). Het resultaat was dat de applicatie crashte op numerieke gegevens.

Voordelen:

  • Snelle code geschreven.

Nadelen:

  • Fouten tijdens runtime.
  • Verlies van vertrouwen in de statische type-afstemming van TypeScript.

Positief geval

We controleren het type voordat we met de methode werken:

if (typeof value === 'string') { return value.toUpperCase(); } else { return value.toString(); }

Voordelen:

  • Volledige veiligheid op het moment van compilatie.
  • Verbeterde onderhoudbaarheid van de code.

Nadelen:

  • De noodzaak om extra controles te schrijven.