Type Guards zijn mechanismen die het mogelijk maken om het type van een variabele in een codeblok te verfijnen op basis van bepaalde controles (bijvoorbeeld met behulp van typeof, instanceof, of speciale functies die uitspraken teruggeven van het type param is SomeType).
Het belangrijkste voordeel is de veiligheid en het uitsluiten van uitvoeringsfouten door type-controle tijdens de compilatie.
Voorbeeld:
interface Fish { swim: () => void } interface Bird { fly: () => void } function isFish(pet: Fish | Bird): pet is Fish { return (pet as Fish).swim !== undefined; } function move(pet: Fish | Bird) { if (isFish(pet)) { pet.swim(); } else { pet.fly(); } }
Hier is de functie isFish een aangepaste type guard.
Nuances:
Vraag: "Zal de TypeScript-compiler altijd alleen vertrouwen op de teruggegeven waarde van de guardfunctie, of wordt er ook een andere analyse binnen de functie gebruikt?"
Antwoord:
De TypeScript-compiler is alleen gebaseerd op de signature van de teruggegeven waarde param is Type. Wat er binnen de guardfunctie gebeurt, wordt niet geanalyseerd op correctheid van de implementatie.
Voorbeeld (gevaarlijke fout!):
function isString(x: any): x is string { return true; } // De compiler denkt dat het altijd een string is, hoewel dat niet zo is: if (isString(123)) { // hier is x van het type string, maar eigenlijk is het een getal }
Verhaal
Op een project met gedeelde DTO's tussen front-end en back-end vergaten we een strikte controle toe te voegen binnen een aangepaste type guard. Als gevolg hiervan werden sommige gegevens ten onrechte beschouwd als het benodigde type, wat leidde tot fouten aan de klantkant bij het proberen een ontbrekende eigenschap te gebruiken.
Verhaal
Een ontwikkelaar schreef een type guard, vertrouwend op een optioneel veld, maar de datavorm staat het helemaal niet toe om dit veld te hebben. Uiteindelijk miste de type switch-case een tak, en de compiler gaf geen waarschuwingen — runtime-excepties ontstonden.
Verhaal
In een van de services, bij de overstap naar TypeScript, vertrouwden ze alleen op ingebouwde type guards (typeof, instanceof). Bij het wijzigen van de objectprototypes werden de controles onjuist, wat leidde tot moeilijk te debuggen bugs in productie.