Interface
Er bestaan een aantal datatypes in TypeScript die we "primitieve" of "eenvoudige" datatypes noemen. Dit is omdat de waarden altijd maar uit 1 enkel ding bestaat. In het hoofdstuk over arrays heb je gezien dat er ook nog een ander soort datatypes bestaat: de complexe datatypes. Deze worden opgebouwd uit meerdere primitieve datatypes.
Een object is een ander voorbeeld van een complex datatype. In JavaScript en TypeScript kom je objecten haast overal tegen. Daarom is het belangrijk om deze te begrijpen en deze te kunnen gebruiken.
Interface van een object literal
We kunnen een object beschrijven aan de hand van een interface . Deze interface beschrijft welke properties een object bevat en kan bevatten. We maken een eigen soort type dat we later kunnen gebruiken bij het declareren van onze variabelen.
Stel dat je het volgende object literal in JavaScript hebt:
Dit object heeft twee properties: name
en age
. De waarde van name
is een string en de waarde van age
is een number. Als we nu een tweede object willen aanmaken en perongeluk een typfout maken, dan zal TypeScript ons niet waarschuwen van deze fout:
TypeScript zal dit als twee verschillende objecten zien. Dit is niet wat we willen. We willen dat TypeScript ons waarschuwt als we een typfout maken. We willen dus een type declareren dat zegt dat een object een name
en een age
property moet hebben. Dit kunnen we doen aan de hand van een interface:
We hebben nu een interface gemaakt die we Person
noemen. Deze interface beschrijft een object dat een name
en een age
property moet hebben. We kunnen nu een variabele declareren van het type Person
:
Als we nu een typfout maken, dan zal TypeScript ons waarschuwen:
Ook is het niet mogelijk om een property toe te voegen die niet in de interface staat:
Ook het weglaten van bepaalde properties zal een foutmelding geven:
Uiteraard moet je ook de data types van de properties respecteren:
Interface in class
Een interface kan ook aan een class gekoppeld worden. In dit geval spreken we dan van een contract dat wordt aangegaan tussen de class en de interface.
Het gedrag bij een class is licht verschillend dan bij de object literal.
Bij gebruik in een class wordt de interface toegevoegd via het implements
keyword. Van zodra de interface aan de class gekoppeld wordt moeten minstens de get/set van de properties in de interface geïmplementeerd worden.
In tegenstelling tot de object literal kunnen in de class wél extra properties toegevoegd worden. De "isAdmin" property toevoegen aan bovenstaande class zal géén fout geven.
Objecten in objecten
Het is ook mogelijk om objecten in andere objecten te gaan steken. Bijvoorbeeld voor ons User object zouden we kunnen kiezen om ook een adres toe te voegen. We zouden deze als aparte eigenschappen kunnen opgeven van het user object maar het is beter om dit in een apart object te steken.
We passen dus de User interface hiervoor aan:
Het type Address
moeten we dan ook nog aanmaken aan de hand van een nieuwe interface.
Nu kunnen we een User object aanmaken gebruik makende van deze interface.
Wil je dan bijvoorbeeld de straat van deze gebruiker op het scherm tonen dan kan je dit doen aan de hand van de dot notatie:
Als we address
zouden niet verplicht maken (optioneel):
dan moet je wel eerst nakijken of address
wel is opgegeven:
anders krijg je deze error:
Interessante operators
De ?. (of optionele chaining) operator
De optionele chaining operator is een nieuwe operator die sinds TypeScript 3.7 beschikbaar is. Deze operator is zeer handig als je objecten in objecten hebt. Stel dat je een object hebt met een aantal properties en je wil een property van een property opvragen. Als je niet zeker bent of de property wel bestaat dan kan je de optionele chaining operator gebruiken.
We hebben hierboven gezien dat we dit kunnen voorkomen door eerst na te kijken of de property wel bestaat aan de hand van een if statement. Dit is echter niet zo handig. Je kan dit nu oplossen aan de hand van de optionele chaining operator:
Als address nu undefined is dan zal de optionele chaining operator undefined teruggeven. Als address wel bestaat dan zal de optionele chaining operator de waarde van street teruggeven.
Zo kunnen we heel diepe objecten gaan opvragen zonder dat we eerst moeten nakijken of de properties wel bestaan:
De ! (of non-null assertion) operator
In TypeScript wordt de ! (non-null assertion) operator gebruikt om aan te geven dat een waarde zeker niet null of undefined zal zijn op het punt waar de operator wordt gebruikt, zelfs als de typechecker dat niet kan garanderen. Dit kan handig zijn in situaties waar je meer weet over de waarde dan TypeScript kan afleiden.
Stel dat je een functie hebt die een default user aanmaakt en returned:
Als we deze functie nu gebruiken en we willen de straat van de default user opvragen dan krijgen we een foutmelding:
Nochtans weten we met zekerheid dat de default user een adres heeft. We kunnen dit aangeven aan de hand van de ! operator:
Let op dat je deze operator niet begint te gebruiken om fouten te verbergen. Je moet er zeker van zijn dat de waarde niet undefined of null kan zijn. Anders zal je een foutmelding krijgen op runtime. Gebruik hem dus niet om de compiler de mond te snoeren.
Last updated