Omgaan met null/undefined
Optional
Soms heb je objecten waarbij niet alle properties een waarde hebben. In TypeScript moet je dit aangeven in de interface van dat object. Stel dat we een Options
interface hebben die gebruikt wordt om een scherm in te stellen.
interface Options {
title: string;
width: number;
height: number;
}
Als je nu
let options : Options = {
title: 'Hello World'
};
// Type '{ title: string; }' is missing the following properties from type 'Options': width, height(2739)
doet dan krijg je een error in typescript want width en height zijn hier niet opgegeven.
Wil je dit toch toelaten dan moet je dit aangeven in de interface van Options aan de hand van de ? operator. Dit geeft aan dat een property optional is.
interface Options {
title: string;
width?: number;
height?: number;
}
Optional chaining
Stel dat we de interface iets aanpassen en de width
en de height
in een apart object plaatsen. Dan krijgen we de volgende situatie
interface Size {
width: number;
height: number;
}
interface Options {
title: string;
size: Size
}
let options: Options = {
title: 'Hello World',
size: {
width: 100,
height: 100
}
};
console.log(options.size.width); // 100
Als we nu size
optioneel maken zoals hiervoor geraken we in de problemen. Onze compiler zal ons dan de volgende foutmelding geven:
interface Size {
width: number;
height: number;
}
interface Options {
title: string;
size?: Size
}
let options: Options = {
title: 'Hello World',
size: {
width: 100,
height: 100
}
};
console.log(options.size.width); // Object is possibly 'undefined'
Omdat we size
optioneel hebben gemaakt bestaat er een kans dat size undefined zou zijn. Dus de typescript compiler waarschuwt ons hiervoor. Hier kunnen we een aantal dingen aan doen. Je zou expliciet kunnen kijken of options.size gelijk is aan undefined aan de hand van een if statement:
let options: Options = {
title: 'Hello World'
};
if (options.size != undefined) {
console.log(options.size.height);
}
of je kan hier optional chaining gebruiken. Je gebruikt hier .?
in plaats van de .
operator:
console.log(options.size?.height); // undefined
en dan krijg je ook geen errors meer te zien. Als je optional chaining gebruikt dan zal de hele expressie als undefined gezien worden als een van de elementen undefined is. In dit geval is size
undefined, dus dan zal de height hiervan ook undefined zijn.
?? Operator (Nullish Coalescing)
Soms wil je een default waarde gebruiken als een property undefined is. Je kan dit doen met de ??
operator:
console.log(options.size?.height ?? 180); // 180
In dit geval wordt de height 180 als de height undefined is.
&& operator
De &&
operator wordt gebruikt om een expressie te evalueren als de linkerkant true
is. Als de linkerkant niet waar is dan zal de rechterkant niet geëvalueerd worden.
const hasLight = false;
const turnOffLight = () => {
console.log('Light is turned off');
};
hasLight && turnOffLight();
In dit geval zal de turnOffLight
functie niet aangeroepen worden omdat de hasLight
false is.
Dit werkt ook met null en undefined:
const light = undefined;
const turnOffLight = () => {
console.log('Light is turned off');
};
light && turnOffLight();
Er zijn veel waarden in JavaScript die als false/true gezien worden. Deze noemen we gewoonlijke truethy en falsy.
- https://developer.mozilla.org/en-US/docs/Glossary/Falsy
- https://developer.mozilla.org/en-US/docs/Glossary/Truthy
.! operator (Non-null assertion)
Heel zelden kom je in situaties terecht dat TypeScript denkt dat een bepaald veld undefined of null kan zijn. Als je zeker bent dat een bepaald veld nooit undefined kan zijn dan kan je ook de !
operator gebruiken om een "Object is possibly undefined" error te vermijden.
Bij de onderstaande code is de TypeScript compilator niet in staat zelf te bepalen of text undefined is of niet. Daarom moet je achter text een uitroepteken zetten om deze error te vermijden.
const duplicate = (text?: string) => {
let fixString = () => {
if (text === null || text === undefined) {
text = "";
}
};
fixString();
return text!.concat(text!);
}
console.log(duplicate("hello"));
Gebruik dit alleen als je zeker bent dat het veld nooit undefined kan zijn. Anders kan je beter de .?
operator gebruiken. Of zet je een default waarde aan de hand van de ??
operator.