Don’t be optional, be explicit
Why you shouldn’t always use
? in Typescript
A popular feature in Typescript lets you mark a given property as optional in a type or interface, these are called optional properties:
These are pretty useful in lots of circumstances as it allows you to keep the code clean and simple but still allow some flexibility when it comes to calling functions and defining objects. In React for example, we use optional boolean properties on
Props in order to make them flexible:
This works great in these cases because the number of properties is usually pretty small. In larger codebases however where these optional properties are used as arguments for functions, things can get a little more complicated:
The problem in this case is that there’s a risk that by not defining or passing each parameter, you could have different behaviours. With the advent of the optional chaining operator (
?.), code that feels natural to write can have odd consequences:
In this case, the code above “optionally” gets the value from the cache if the cache is provided. This makes sense from within the function’s scope, but outside, this tradeoff isn’t quite that clear.
Rather than relying on optional properties, you could instead still leverage the optional chaining operator by explicitly requiring that the value be specified, even if it’s not available:
This forces developers to specify the absence of the parameter rather than letting it silently get ignored, leading to the following:
Being explicit with the properties passed allows users to always see explicitly what’s being passed to the function rather then being silent. This is even compatible with the optional chaining operator as it forces users to still pass the property but it will return
undefined if the property is not defined:
I’m definitely not advocating for all properties to be explicit, but for those involved with critical control flows in functions and your applications, you’re probably better off being explicit with those properties instead of leaving them optional.