Optionele eigenschappen in TypeScript worden aangeduid met een vraagteken (?) achter de naam van de eigenschap. Dit betekent dat de eigenschap ofwel is gedefinieerd, ofwel afwezig kan zijn in het object. Dit is handig bij het beschrijven van structuren waarin niet alle velden verplicht zijn.
Voorbeeld:
interface User { id: number; name?: string; } const u1: User = { id: 1 }; // OK const u2: User = { id: 2, name: 'Ivan' }; // OK
Fijnere details:
undefined zijn, maar ook volledig afwezig in het object.if (user.name)) maakt geen onderscheid tussen undefined en afwezigheid.undefined kan zijn en het aanroepen van methoden/eigenschappen zonder controle.Om je te beschermen:
undefined:if (user.name !== undefined) { console.log(user.name.toUpperCase()); }
console.log(user.name?.toUpperCase());
Als een object de interface
{ foo?: string }beschrijft, kan de eigenschapfoodan altijd alleen een string ofundefinedzijn? Kan je er bijvoorbeeld de waardenullin opslaan?
Onjuiste antwoord:
undefined zijn, iets anders is niet toegestaan."Juiste antwoord:
null toewijst, staat TypeScript dit toe, maar alleen als het type is uitgebreid naar string | null. Standaard is dit alleen string of undefined.interface A { foo?: string } let x: A = { foo: null }; // Fout!
Verhaal
In een groot project kwamen sommige objecten van de server zonder bepaalde optionele velden. De programmeur riep direct methoden op deze eigenschappen aan (bijvoorbeeld, toLowerCase()), wat leidde tot runtime-fouten als het veld ontbrak. Om het probleem op te lossen, implementeerde het team strenge controles en lintersregels voor toegang tot optionele velden.
Verhaal
In logische uitdrukkingen verwarden ze de aanwezigheid van de eigenschap met zijn waarheidswaarde: if (user.email) werkte niet voor lege strings, hoewel de eigenschap was gedefinieerd. Dit leidde tot een bug waardoor sommige meldingen niet naar gebruikers werden verzonden.
Verhaal
Het team besloot de waarde null aan een optionele eigenschap toe te wijzen, in de veronderstelling dat dit correct was. TypeScript gaf een foutmelding, en om dit te omzeilen moest het type worden uitgebreid naar string | null, wat een herziening van de hele bedrijfslogica voor deze objecten vereiste.