strictNullChecks is a great option, which can help developers avoid many potential runtime errors. So I recently started to refactor my code with this option enabled. But then I came across a small but slightly annoying scenario:
if (array?.length > 0) {
// do something with `array`
}
I have a habit of using such syntax to obtain a non-empty array, taking advantage of the JavaScript feature that comparing anything with undefined using < or > results in false. However, this syntax is disallowed under strictNullChecks, which means I have to write it in a verbose way:
if (array != null && array.length > 0) {
// do something with `array`
}
Well, maybe not that verbose, but when array is a long chaining expression instead of a simple variable, the previous syntax really saves your life (or otherwise you'll have to choose between repeating this long expression or assigning it to a variable beforehand).
Is there another option to allow this specific scenario? Since I don't want to lose the benefit of strictNullChecks either.
Or some inspirations on why TypeScript decided to ban comparing undefined with other values using < or > are also welcomed. I understand that many view this feature more of a pitfall which should be circumvented by every means, since it's not very semantic, especially for starters. But I do appreciate the convenience of using it in such a scenario. So is clarity the only consideration for banning it? Or there are still some potential runtime impacts that I've left out?
Well, as pointed out in the comments, the scenario above could be simply solved by removing > 0, since both undefined and 0 are considered falsy.
While there are other scenarios where we want to compare a possibly undefined or null value with a non-zero number, array?.length ?? 0 will do the trick (but TypeScript won't deduce that array is neither undefined nor null in the following block, we still need the non-null assertion operator).
So, the major problem is basically solved. But I'm still curious about the motivation that drives TypeScript developers to prohibit comparison between possibly null or undefined numbers with strictNullChecks on. Therefore, I decided to keep this question open for discussion.
As you noticed array?.length > 0 is not allowed with strictNullChecks: If array is undefined, it reduces to undefined > 0.
The if condition can be simplified in a way which works fine with strictNullChecks.
if (array?.length) {
// process non-empty array
}
The code above relies on the fact that undefined and 0 are falsy, and all non-zero numbers are truthy.
If the code inside the if block can accept empty arrays, the condition can be further simplified to:
if (array) {
// process empty array or non-empty array
}
While I'm not in a position to discuss design decisions, strictNullChecks on says:
With strictNullChecks on, when a value is null or undefined, you will need to test for those values before using methods or properties on that value.
If property or method access is disallowed on possibly undefined object, it is consistent to disallow <,<= operators as well. Not only being consistent, it removes surprising behaviour of JS: Why isn't undefined less than 1?
// JS
undefined <= undefined // false
undefined > undefined // false
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With