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