user3509546
user3509546

Reputation: 3597

In Typescript, How to check if a string is Numeric

In Typescript, this shows an error saying isNaN accepts only numeric values

isNaN('9BX46B6A')

and this returns false because parseFloat('9BX46B6A') evaluates to 9

isNaN(parseFloat('9BX46B6A'))

I can still run with the error showing up in Visual Studio, but I would like to do it the right way.

Currently, I have written this modified function -

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

Upvotes: 346

Views: 524366

Answers (18)

kroczku
kroczku

Reputation: 1

Here's typed version for utils, or sth

export const isNumber = (value: unknown): value is number =>
  Number.isFinite(value);

Upvotes: 0

David Brito
David Brito

Reputation: 141

You could use a regex to match a numeric string like this:

const RE = /^(?:[+-]?(?=\.\d|\d)(?:\d+)?(?:\.?\d*)(?:[eE][+-]?\d+)?)$/

function isNumericString(str) {
  return RE.test(str)
}

Upvotes: 1

Gil Epshtain
Gil Epshtain

Reputation: 9801

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

Upvotes: 78

Collin
Collin

Reputation: 444

This works for special cases, e.g. nulls

if(!isNaN(yourValue) && yourValue !== true && yourValue !== false) {
    // then it's a number
} else {
    // then it's not a number
}

Upvotes: 0

Richard Lee
Richard Lee

Reputation: 2245

Update

This method is no longer available in rxjs v6


I'm solved it by using the isNumeric operator from rxjs library (importing rxjs/util/isNumeric

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

. . .

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

Upvotes: 61

Sonic Soul
Sonic Soul

Reputation: 24899

here's my trusty isNumber function. use it wisely

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

tests

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)
})

Upvotes: 3

mbarish-me
mbarish-me

Reputation: 947

 const isNumeric = (value: string): boolean =>
  !new RegExp(/[^\d]/g).test(value.trim());

If you want to allow decimal point

   const isNumeric = (value: string): boolean =>
      !new RegExp(/[^\d.]/g).test(value.trim());

Upvotes: 0

Felix
Felix

Reputation: 1810

Considering that your variable could be string or number or any type - for full numbers (non-floats) in Angular/Typescript you can use:

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

Edited as pointed out by @tarrbal - we CANNOT use just:

Number.isInteger(yourVariable);

To prove check out these 3 tests:

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);
})

and these 3 results:

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

Upvotes: 5

Krzysztof Grzybek
Krzysztof Grzybek

Reputation: 9406

My solution:

 function isNumeric(val: unknown): val is string | number {
  return (
    !isNaN(Number(Number.parseFloat(String(val)))) &&
    isFinite(Number(val))
  );
}
// true
isNumeric("-10");
isNumeric("0");
isNumeric("0xff");
isNumeric("0xFF");
isNumeric("8e5");
isNumeric("3.1415");
isNumeric("+10");
isNumeric("144");
isNumeric("5");

// false
isNumeric("-0x42");
isNumeric("7.2acdgs");
isNumeric("");
isNumeric({});
isNumeric(NaN);
isNumeric(null);
isNumeric(true);
isNumeric(Infinity);
isNumeric(undefined);
isNumeric([]);
isNumeric("some string");

Upvotes: 1

LCIII
LCIII

Reputation: 3626

Scrolled through each answer and was surprised that this simple one-liner wasn't presented yet:

const isNumber = (val: string | number) => !!(val || val === 0) && !isNaN(Number(val.toString()));

Upvotes: 2

Mir Mohamed Ullah
Mir Mohamed Ullah

Reputation: 45

if var sum=0; var x;

then, what about this? sum+=(x|0);

Upvotes: -3

Hung Vu
Hung Vu

Reputation: 5914

My simple solution here is:

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

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

Upvotes: 19

C Snover
C Snover

Reputation: 18766

The way to convert a string to a number is with Number, not parseFloat.

Number('1234') // 1234
Number('9BX9') // NaN

You can also use the unary plus operator if you like shorthand:

+'1234' // 1234
+'9BX9' // NaN

Be careful when checking against NaN (the operator === and !== don't work as expected with NaN). Use:

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

Upvotes: 596

Nick H
Nick H

Reputation: 494

Simple answer: (watch for blank & null)

isNaN(+'111') = false;
isNaN(+'111r') = true;
isNaN(+'r') = true;
isNaN(+'') = false;   
isNaN(null) = false;   

https://codepen.io/CQCoder/pen/zYGEjxd?editors=1111

Upvotes: 9

James Paterson
James Paterson

Reputation: 2890

You can use the Number.isFinite() function:

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

Note: there's a significant difference between the global function isFinite() and the latter Number.isFinite(). In the case of the former, string coercion is performed - so isFinite('0') === true whilst Number.isFinite('0') === false.

Also, note that this is not available in IE!

Upvotes: 17

ZiiMakc
ZiiMakc

Reputation: 36806

Most of the time the value that we want to check is string or number, so here is function that i use:

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

Codesandbox tests.

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, () => {}]

Upvotes: 4

Jan
Jan

Reputation: 458

I would choose an existing and already tested solution. For example this from rxjs in typescript:

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

Without rxjs isArray() function and with simplefied typings:

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

You should always test such functions with your use cases. If you have special value types, this function may not be your solution. You can test the function here.

Results are:

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

As you can see, you have to be careful, if you use this function with enums.

Upvotes: 10

basarat
basarat

Reputation: 276229

Whether a string can be parsed as a number is a runtime concern. Typescript does not support this use case as it is focused on compile time (not runtime) safety.

Upvotes: -6

Related Questions