Reputation: 3597
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
Reputation: 1
Here's typed version for utils, or sth
export const isNumber = (value: unknown): value is number =>
Number.isFinite(value);
Upvotes: 0
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
Reputation: 9801
function isNumber(value?: string | number): boolean
{
return ((value != null) &&
(value !== '') &&
!isNaN(Number(value.toString())));
}
Upvotes: 78
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
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
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
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
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
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
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
Reputation: 5914
My simple solution here is:
const isNumeric = (val: string) : boolean => {
return !isNaN(Number(val));
}
// isNumberic("2") => true
// isNumeric("hi") => false;
Upvotes: 19
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
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
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
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));
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
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;
}
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
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