在Typescript中,如何检查一个字符串是否为数字

320
在TypeScript中,这会显示一个错误,指出isNaN仅接受数字值。
isNaN('9BX46B6A')

这会返回false,因为parseFloat('9BX46B6A')计算结果为9

isNaN(parseFloat('9BX46B6A'))

我仍然可以在Visual Studio中看到错误的情况下运行,但我想按照正确的方式做。

目前,我编写了这个修改后的函数 -

static isNaNModified = (inputStr: string) => {
    var numericRepr = parseFloat(inputStr);
    return isNaN(numericRepr) || numericRepr.toString().length != inputStr.length;
}

可能是TypeScript将字符串转换为数字的重复问题。 - Wesley Coetzee
16个回答

558
将字符串转换为数字的方法是使用 Number,而不是 parseFloat
Number('1234') // 1234
Number('9BX9') // NaN
您也可以使用一元加运算符,如果您喜欢简写方式:
+'1234' // 1234
+'9BX9' // NaN

检查 NaN 时要小心(使用 ===!== 操作符与 NaN 结合使用时无法按预期工作)。推荐使用:

 isNaN(+maybeNumber) // returns true if NaN, otherwise false

25
这是否意味着执行以下代码:if (isNaN(+possibleNumberString)) 是一种有效的检查方式? - Mathijs Segers
10
为什么在使用 parseIntparseFloat 时会选择使用 NumberNumber('') 返回 0,而 parseInt('') 返回 NaN,后者符合我的预期更多。请解释原因。 - Didii
14
如原问题中所提到的,parseInt('9BX9')(和parseFloat('9BX9'))将返回9,而不是NaN。如果您不想将空字符串转换为0,请先显式地检查是否为空字符串。 - C Snover
2
如果你想检查它,使用isNaN(Number(what_ever))而不是Number(what_ever) === Nan - k0pernikus
3
“Number”不是 TypeScript 的东西,它是一个内置的 EcmaScript 构造函数(constructor function),当作为函数而非构造函数调用时,它接受一个值并返回一个数值类型的基本数据类型。 - C Snover
显示剩余8条评论

68
function isNumber(value?: string | number): boolean
{
   return ((value != null) &&
           (value !== '') &&
           !isNaN(Number(value.toString())));
}

如果value未定义,在尝试调用其toString()方法时,这会抛出异常吗? - LCIII
1
@LCIII - 如果值为 undefined,那么 value != null 就是 false,因此 if 语句(在 return 中)将不会通过第一行代码。因为 if 行之间有一个 && - Gil Epshtain

58

更新

在rxjs v6中,此方法已不再可用。


我使用了rxjs库中的isNumeric操作符(导入rxjs/util/isNumeric),解决了这个问题。

import { isNumeric } from 'rxjs/util/isNumeric';

. . .

var val = "5700";
if (isNumeric(val)){
   alert("it is number !");
}

13
rxjs v6 中不再支持该方法。 - Logic01
8
需要使用React来检测一个数字是否为数值似乎有些过度了... https://github.com/ReactiveX/rxjs/blob/master/src/internal/util/isNumeric.ts(好奇的人可以看一下) - Azeroth2b
Richard Lee,请更新你的答案。 - Because i hate myself

17

我这里的简单解决方案是:

const isNumeric = (val: string) : boolean => {
   return !isNaN(Number(val));
}

// isNumberic("2") => true
// isNumeric("hi") => false;

2
这将把空格、空等视为数字。 - Viswanath Lekshmanan
这个不起作用,因为如果字符串中包含任何数字,它将被解释为数字。 - Janine White
以下这些情况不起作用:Number("") ==0 Number(null)== 0 Number(true)==1 Number(Infinity)==Infinity Number([])==0 - Anthony Brenelière
这在你只需要检查“强制转换”为数字是否成功的情况下很有用,并将空格视为“0”,这正是我所需要的。 - Aleksandar Stefanović

16
你可以使用Number.isFinite()函数:
Number.isFinite(Infinity);  // false
Number.isFinite(NaN);       // false
Number.isFinite(-Infinity); // false
Number.isFinite('0');       // false
Number.isFinite(null);      // false

Number.isFinite(0);         // true
Number.isFinite(2e64);      // true

注意:全局函数isFinite()和后者Number.isFinite()之间存在显着差异。在前者的情况下,会执行字符串强制转换-因此isFinite('0') === true,而Number.isFinite('0') === false

另外,请注意IE浏览器不支持此函数!


1
但是...TS2345:类型为“'1'”的参数无法分配给类型为“number”的参数。它需要Number.isFinite(Number('0')); - Mcgri

9

7

我会选择一个已经存在并经过测试的解决方案。例如这个在typescript中使用rxjs:

function isNumeric(val: any): val is number | string {
  // parseFloat NaNs numeric-cast false positives (null|true|false|"")
  // ...but misinterprets leading-number strings, particularly hex literals ("0x...")
  // subtraction forces infinities to NaN
  // adding 1 corrects loss of precision from parseFloat (#15100)
  return !isArray(val) && (val - parseFloat(val) + 1) >= 0;
}

rxjs/isNumeric.ts

没有使用rxjs的isArray()函数,只使用简化版本的类型声明:

function isNumeric(val: any): boolean {
  return !(val instanceof Array) && (val - parseFloat(val) + 1) >= 0;
}

你应该始终使用你的用例测试这样的函数。如果你有特殊的值类型,这个函数可能不是你的解决方案。 你可以在这里测试这个函数。

结果如下:

enum         : CardTypes.Debit   : true
decimal      : 10                : true
hexaDecimal  : 0xf10b            : true
binary       : 0b110100          : true
octal        : 0o410             : true
stringNumber : '10'              : true

string       : 'Hello'           : false
undefined    : undefined         : false
null         : null              : false
function     : () => {}          : false
array        : [80, 85, 75]      : false
turple       : ['Kunal', 2018]   : false
object       : {}                : false

正如您所见,如果您在使用此功能时使用枚举类型,请务必小心。


1
Typescript 称之为“类型保护”。 - serg06

5

考虑到您的变量可能是字符串、数字或任何类型,对于 Angular/Typescript 中的完整数字(非浮点数),您可以使用以下代码:

var isFullNumber: boolean = 
    Number.isInteger(Number(yourVariable)) && yourVariable !== null;

根据 @tarrbal 的指出,我们不能仅仅使用:

Number.isInteger(yourVariable);

为了证明这一点,请看以下三个测试:

let testVariables = [0, 1, "0", "1", "A", {}, -3, 0.1, NaN, null, undefined]; 

let isFullNumber: boolean;
let ix: number = 1;
testVariables.forEach(v => {
isFullNumber = Number.isInteger(v);                         // <---
console.log(ix++, ': ', v, isFullNumber);
})

console.log('--------------');

ix = 1;
testVariables.forEach(v => {
isFullNumber = Number.isInteger(Number(v));                 // <---
console.log(ix++, ': ', v, isFullNumber);
})

console.log('--------------');
ix = 1;
testVariables.forEach(v => {
isFullNumber = Number.isInteger(Number(v)) && v !== null;   // <---
console.log(ix++, ': ', v, isFullNumber);
})

以下是这3个结果:

1   :       0           true
2   :       1           true
3   :       0           false <- would expect true
4   :       1           false <- would expect true
5   :       A           false
6   :       {}          false
7   :       -3          true
8   :       0.1         false
9   :       NaN         false
10  :       null        false
11  :       undefined   false
----------------------------
1   :       0           true
2   :       1           true
3   :       0           true
4   :       1           true
5   :       A           false
6   :       {}          false
7   :       -3          true
8   :       0.1         false
9   :       NaN         false
10  :       null        true <- would expect false
11  :       undefined   false
----------------------------
1   :       0           true
2   :       1           true
3   :       0           true
4   :       1           true
5   :       A           false
6   :       {}          false
7   :       -3          true
8   :       0.1         false
9   :       NaN         false
10  :       null        false
11  :       undefined   false

4
Number.isInteger 只是告诉您 yourVariable 是否为整数,而 yourVariable 已经是 number 类型,不能用于字符串。因此, Number.isInteger(Number(yourVariable)) 或许可以解决问题。 - tarrball

3

这是我的可靠 isNumber 函数,要明智使用它

function isNumber(numStr: string) {
  return !isNaN(parseFloat(numStr)) && !isNaN(+numStr)
}

测试

it("test valid isNumber", () => {
  expect(isNumber("0")).toEqual(true)
  expect(isNumber("-1")).toEqual(true)
})

it("test invalid isNumber", () => {
  expect(isNumber('" 1000 "')).toEqual(false)
  expect(isNumber('" 100,00.00 "')).toEqual(false)
  expect(isNumber("100,00.00")).toEqual(false)
  expect(isNumber("")).toEqual(false)
  expect(isNumber(null as any as string)).toEqual(false)
  expect(isNumber("abc")).toEqual(false)
  expect(isNumber("10%")).toEqual(false)
  expect(isNumber("#10")).toEqual(false)
  expect(isNumber("2^10")).toEqual(false)
  expect(isNumber("2!")).toEqual(false)
  expect(isNumber("(10)")).toEqual(false)
  expect(isNumber("10px")).toEqual(false)
})

2

大多数情况下,我们要检查的值是字符串或数字,因此这里是我使用的函数:

const isNumber = (n: string | number): boolean => 
    !isNaN(parseFloat(String(n))) && isFinite(Number(n));

Codesandbox 测试

const willBeTrue = [0.1, '1', '-1', 1, -1, 0, -0, '0', "-0", 2e2, 1e23, 1.1, -0.1, '0.1', '2e2', '1e23', '-0.1', ' 898', '080']

const willBeFalse = ['9BX46B6A', "+''", '', '-0,1', [], '123a', 'a', 'NaN', 1e10000, undefined, null, NaN, Infinity, () => {}]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接