TypeScript Quirks: Getting grandma's number - NaN
Everybody loves their Nan (or at least most of us)… but I doubt very many of us love NaN
, and with good reason.
Below we have a function that takes a number, and adds one to it.
const plus1 = (num: number) => num + 1;
We can call it like this:
const two = plus1(1); // Happy
But we can’t call it like this:
const something = plus1(); // Not happy
So, what if we were to allow our argument to be optional?
const plus1 = (num?: number) => num + 1;
Now both of our the function calls work, and it happily compiles. But why? You shouldn’t be able to add a number
to undefined
and get back a number
. What if we set an explicit return type?
const plus1 = (num?: number): number => num + 1;
Nope. We can still call plus1
with no arguments and this is fine. The reason for this is because undefined
plus a number
is NaN
, and NaN
is a number… Yeah, crazy.
TypeScript inferred that our return type would be number, so adding our own definition does not help at all. This code is technically correct. So how might we overcome something like this? Defaults!?!?… It really depends on the use case, but I just thought you should know that NaN
happens.
If we add a default to our function as it is, it will not compile. This is because you can’t say that something is both optional, and will have a value if it is not defined. They basically contradict eachother.
const plus1 = (num?: number = 0): number => num + 1; // Wrong!
With defaults you can remove the optional part. TypeScript knows that if it has a default, it is optional.
const plus1 = (num: number = 0): number => num + 1; // Nice
We can also take out that explicit return type.
const plus1 = (num: number = 0) => num + 1; // Nicer
Much better.
Now we can happily call our function in the following ways.
const one = plus1(); // Happy
const oneAgain = plus1(undefined); // Happy
const two = plus1(1); // Happy