Note that type narrowing works in the else
statement as well. In other words TypeScript uses the typeof
check to eliminate the possibility that value
is undefined, and therefore it must be a number in the else block.
undefined
is also a falsy value. If you use it in an if
statement by itself, it works the same as false
. Remember that both 0 and an empty string are falsy as well though!
Using optional values like this is very common in programming, and we'll come back to this later. It's generally useful to have a distinct value that means "nothing" or "not set" as opposed to an actual value. It might be tempting to use a special value like 0 or -1 to represent a number that is not set, but in some cases all possible numbers would be valid to be set, and so it's generally a better idea to use a different type of value to represent the empty state.
null
Rather confusingly, there is a second empty value in TypeScript: null
. Like undefined
it can be used as both a type and a value, and is falsy if used in an if
statement. Why does it exist? TypeScript inherits both undefined
and null
from JavaScript, and JavaScript having two special empty values is widely regarded as a design mistake. It's too late to change it, so unfortunately it's just a slightly weird thing we have to live with.
Generally undefined
is the empty value used by the JavaScript language itself. Construct-specific features (which we'll get on to later) generally use null
. The difference doesn't matter much - in many cases it won't affect the code you write.
One other quirk to be aware of is typeof null
is "object"
. This is also widely regarded as a mistake - it would make more sense if it was "null"
. Unfortunately this is another thing that's too late to change. Oops! If you ever design a programming language, be sure to think through the design very carefully!