TypeScript isNan 只接受数字

TypeScript isNan only accepts a number

我使用 WebStorm 2016.2.2、TypeScript 2.1,Node.js。

出于某种原因,isNan 被声明为只接受数字的函数:

declare function isNaN(number: number): boolean;

我试过改成any,好像对TSC没有影响。我仍然得到同样的错误:

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

我的代码(简体):

isNan("10");

我怎样才能solve/workaround呢?


编辑:

请注意,根据规范,isNan 的参数可以是任何类型:Number.isNan()

另外:我的代码被简化了。我实际上收到一个参数,它可能是一个字符串或一个数字,如果它是一个字符串,它可能是一个我想转换为数字(“10”)的字符串数字或一个简单的字符串("Hello world" ).

我不想通过包含我的整个代码来使这个问题变长,但因为它造成了混淆,这是我的真实代码:

            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 的工作方式。

首先将输入转换为数字

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

然后用isNan函数检查结果:

isNaN(Number("abc"))

首先,只有number类型的值可以是NaN。因此,如果静态上下文告诉您您的值是 string 类型,您可以确定它不是 NaN。如果你有一个 string|number 类型的值(顺便说一句,应该避免),你仍然可以决定如何处理它。严格来说,字符串值 "foo" 不是 NaN,因为 NaN 是 IEEE 标准中为浮点数指定的特定值。但是,在 javascript 中,isNaN("foo") 仍然为真,因为函数 will coerect the string to a number 首先,并且该强制转换导致 NaN。 Typescript 试图在这里利用类型,它试图阻止您在不应该使用的地方使用 isNaN

我建议您以不同的方式实现您的代码。
原因:

  1. 它可能很短,但并不容易理解发生了什么
  2. 在这里使用 isNaN 不是最佳选择:isNaN("") returns false 也是

您最好尝试将该值转换为数字并检查它是否为 NaN(如@smnbbrv 所写):

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

编辑

您可以将您的值传递为 any:

isNaN(ctualValue as any)

绕过编译器检查。

您可以通过在 isNaN 中使用 parseInt 来解决这个问题。如果 parseInt returns NaN,检查 isNaN 仍然有效。你的 Typescript 错误将得到解决。

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

具有讽刺意味的是,只有数字可以 NaN,您需要先将字符串转换为数字。

一个非常简单的方法是使用一元加运算符。

所以你可以做一个简单的isNaN(+"10")

请记住,像 +""+" "+"\n" 这样的东西是 0!

在接受的答案中,!Number.isNaN(Number(expectedValue)) 对于空字符串 ('') 和空白字符串 (' ') 仍然 returns 正确。并将这些转换为数字将导致 0.

我不是 JavaScript 开发人员,而且 – 尤其是来自 .Net – 它对我来说也很疯狂,但这就是我所做的似乎有效的事情:

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

如果您知道更明智的解决方案,请务必对其进行编辑!

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

从Google找到这个答案,并从这里的各种答案和评论中得出我的答案;我的答案是使用:

isNaN(Number(string))

这将正确地告诉我字符串是否为数字。

我之前使用的是 parseInt(),但如果字符串类似于 123abc,则此操作失败,因为 parseInt 只是丢弃字母(有时有用,但在这里没有用)。

注意:我很高兴 Number('') 的计算结果为零,但如果不是,这不是解决方案!

通过 isNaN(value as unknown as number) 让我的编译器满意。 就我而言,我使用 isNaN() 来防止“NaN”在加载数据时闪烁。这允许我将 string 传递给 isNaN(),因为接口需要一个字符串。