TypeScript isNan only accepts a number

Javascriptnode.jsTypescriptWebstorm

Javascript Problem Overview


I work with WebStorm 2016.2.2, TypeScript 2.1, Node.js.

For some reason, isNan is declared as a function that only accepts a number:

declare function isNaN(number: number): boolean;

I tried to change it to any, but it looks like it doesn't influence on the TSC. I still get the same error:

> Argument of type 'string' is not assignable to parameter of type > 'number'

My code (simplified):

isNan("10");

How can I solve/workaround it?


Edit:

Notice that according to specification, isNan's parameter can be any type: Number.isNan()

Also: My code was simplified. I actually receive a parameter that may be either a string or a number, and if it's a string it may be either a stringy number that I would like to convert to number ("10") or a simple string ("Hello world").

I didn't want to make this question long by including my entire code, but because it caused confusion, this is my real code:

            if (typeof expectedValue === "string" && !isNaN(expectedValue)) {
                    expectedValue = +expectedValue;
                }

            if (typeof actualValue === "string" && !isNaN(ctualValue)) {
                actualValue = +actualValue;
            }

            switch (this.operator) {
                case Operator.equal:
                    return actualValue == expectedValue;
                case Operator.notEqual:
                    return actualValue === undefined || actualValue != expectedValue;
                case Operator.greaterThan:
                    return actualValue > expectedValue;
                case Operator.littleThan:
                    return actualValue < expectedValue;
                case Operator.greaterOrEqual:
                    return actualValue >= expectedValue;
                case Operator.littleOrEqual:
                    return actualValue <= expectedValue;
            }

Javascript Solutions


Solution 1 - Javascript

I advise you to implement your code differently.
The reasons:

  1. It might be short, but it's not easy to understand what's going on
  2. Using isNaN isn't the best option here: isNaN("") returns false as well

You better try to convert the value into a number and check if that's NaN or not (as @smnbbrv wrote):

if (typeof expectedValue === "string" && !Number.isNaN(Number(expectedValue))) {
    expectedValue = Number(expectedValue);
}

Edit

You can pass your value as any:

isNaN(ctualValue as any)

To bypass the compiler check.

Solution 2 - Javascript

You should not solve it because this is how JavaScript works.

Just cast the input to number first

Number("10") // 10
Number("abc") // NaN

and then check the result with the isNan function:

isNaN(Number("abc"))

Solution 3 - Javascript

As ironically only numbers can be NaN, you need to transform strings into numbers first.

A very simple way to do this is the unary plus operator.

So you can do a simple isNaN(+"10").

Keep in mind that thing like +"", +" " and +"\n" are 0!

Solution 4 - Javascript

First of all, only values of type number can be NaN. So if the static context tells you your value is of type string for example, you can be sure that it is not a NaN. If you have a value with type string|number (which should be avoided btw) you can still decide how you handle this. Strictly speaking, the string value "foo" is not NaN, as NaN is a specific value specified in the IEEE standard for float numbers. But still, in javascript, isNaN("foo") will be true, as the function will coerect the string to a number first, and that coerection results in a NaN. Typescript tries to take advantage of types here, it tries to prevent you from using isNaN where you should not.

Solution 5 - Javascript

You can solve this by using parseInt inside your isNaN. The check isNaN will still work if the parseInt returns NaN. And your Typescript error will be solved.

if (typeof actualValue === "string" && !isNaN(parseInt(actualValue, 10))) {
  actualValue = +actualValue;
}

Solution 6 - Javascript

In the accepted answer, !Number.isNaN(Number(expectedValue)) still returns true for empty string ('') and whitespace strings (' '). And converting these to number will result in 0.

I'm not a JavaScript developer, and – especially coming from .Net – it looks insane to me as well, but this is what I've done that seems to work:

private static isNumber(value: any): boolean {
  return (typeof value === 'number' && !isNaN(value))
      || ((typeof value === 'string') && value.trim() != '' && !isNaN(Number(value)))
  }

If you know a saner solution, be sure to edit this!

console.log(isNumber([]));		// false
console.log(isNumber({}));		// false
console.log(isNumber(""));		// false
console.log(isNumber("   "));	// false
console.log(isNumber(" 1  "));	// true <= note
console.log(isNumber(" 1  2"));	// false
console.log(isNumber("1"));		// true
console.log(isNumber(1));		// true

Solution 7 - Javascript

Found this answer from Google, and reached my answer from the various answers and comments here; my answer is to use:

isNaN(Number(string))

This will correctly tell me if the string is a number.

I was previously using parseInt(), but this fails if the string is something like 123abc as parseInt just discards the letters (useful sometimes, but not here).

Note: I'm happy that Number('') evaluates to zero, but if your not, this isn't the solution!

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionAlonView Question on Stackoverflow
Solution 1 - JavascriptNitzan TomerView Answer on Stackoverflow
Solution 2 - JavascriptsmnbbrvView Answer on Stackoverflow
Solution 3 - Javascriptpa1ndView Answer on Stackoverflow
Solution 4 - JavascriptTamas HegedusView Answer on Stackoverflow
Solution 5 - JavascriptEllajiView Answer on Stackoverflow
Solution 6 - JavascriptLeakyView Answer on Stackoverflow
Solution 7 - JavascriptBen RobinsonView Answer on Stackoverflow