How can I check if a string is a valid number?
Categories:
Robust JavaScript Number Validation: Techniques and Best Practices

Learn various JavaScript techniques to accurately determine if a string represents a valid numeric value, covering common pitfalls and edge cases.
In JavaScript, validating whether a string is a valid number is a common task, especially when dealing with user input or data parsed from external sources. Simply checking the type isn't enough, as a string like "123"
is numerically valid but still a string. This article explores several robust methods to perform this validation, discussing their strengths, weaknesses, and appropriate use cases.
Understanding the Challenge of Numeric Validation
The core challenge lies in JavaScript's flexible type coercion. Many operations will implicitly convert strings to numbers, which can lead to unexpected results if not handled carefully. For instance, "10" / "2"
evaluates to 5
, but "hello" / "2"
results in NaN
(Not-a-Number). Our goal is to identify strings that can be reliably converted to a finite number, excluding NaN
and Infinity
.
flowchart TD A[Input String] --> B{Is it empty or just whitespace?} B -- Yes --> C[Invalid] B -- No --> D{Can it be parsed as a number?} D -- Yes --> E{Is the parsed value NaN or Infinity?} E -- Yes --> C E -- No --> F[Valid Number] D -- No --> C
Decision flow for validating if a string is a valid number.
Method 1: Using Number()
and isNaN()
One of the most straightforward approaches involves attempting to convert the string to a number using the global Number()
function (or unary plus operator +
) and then checking if the result is NaN
using isNaN()
. This method handles various numeric formats, including integers, floats, and scientific notation.
function isValidNumber(str) {
if (typeof str !== 'string' || str.trim() === '') {
return false; // Not a string or empty/whitespace only
}
const num = Number(str);
return !isNaN(num) && isFinite(num);
}
console.log(isValidNumber("123")); // true
console.log(isValidNumber("3.14")); // true
console.log(isValidNumber("-10")); // true
console.log(isValidNumber("0")); // true
console.log(isValidNumber(" 50 ")); // true
console.log(isValidNumber("1e5")); // true (scientific notation)
console.log(isValidNumber("abc")); // false
console.log(isValidNumber("")); // false
console.log(isValidNumber(" ")); // false
console.log(isValidNumber(null)); // false (not a string)
console.log(isValidNumber(undefined)); // false (not a string)
console.log(isValidNumber("Infinity")); // false (isFinite check)
console.log(isValidNumber("NaN")); // false (isNaN check)
Using Number()
, isNaN()
, and isFinite()
for robust string-to-number validation.
isFinite()
global function is crucial here. While !isNaN(num)
checks if the value is not NaN
, isFinite(num)
ensures it's not Infinity
or -Infinity
, which Number()
can also produce from string inputs like "Infinity"
.Method 2: Regular Expressions for Stricter Validation
For scenarios requiring stricter control over the format of the numeric string (e.g., disallowing leading/trailing spaces, specific decimal formats, or only positive integers), regular expressions are a powerful tool. This method allows you to define exactly what constitutes a 'valid' number string.
function isStrictlyNumeric(str) {
if (typeof str !== 'string' || str.trim() === '') {
return false;
}
// Regex for optional sign, one or more digits, optional decimal part
// Allows integers and floats, no leading/trailing spaces
const numericRegex = /^-?\d+(\.\d+)?$/;
return numericRegex.test(str);
}
console.log(isStrictlyNumeric("123")); // true
console.log(isStrictlyNumeric("3.14")); // true
console.log(isStrictlyNumeric("-10")); // true
console.log(isStrictlyNumeric("0")); // true
console.log(isStrictlyNumeric(" 50 ")); // false (leading/trailing spaces)
console.log(isStrictlyNumeric("1e5")); // false (scientific notation not allowed by this regex)
console.log(isStrictlyNumeric("abc")); // false
console.log(isStrictlyNumeric("")); // false
console.log(isStrictlyNumeric(" ")); // false
console.log(isStrictlyNumeric(".5")); // false (requires leading digit)
console.log(isStrictlyNumeric("5.")); // true (some definitions allow this)
Using a regular expression for strict numeric string validation.
1e5
) or hexadecimal numbers (0xFF
) unless explicitly included in the pattern. They are best for enforcing a specific format rather than general numeric parsing.Method 3: parseFloat()
/ parseInt()
with isNaN()
and String Comparison
For more nuanced control, especially when dealing with strings that might contain non-numeric characters after a valid number (e.g., "10px"
), parseFloat()
or parseInt()
can be combined with isNaN()
and a string comparison. This method checks if the entire string was consumed by the parsing function.
function isValidNumberStrictParse(str) {
if (typeof str !== 'string' || str.trim() === '') {
return false;
}
const trimmedStr = str.trim();
const parsedNum = parseFloat(trimmedStr);
// Check if it's a valid number AND if the original string (trimmed) matches
// the string representation of the parsed number.
// This ensures no extra characters were present.
return !isNaN(parsedNum) && isFinite(parsedNum) && String(parsedNum) === trimmedStr;
}
console.log(isValidNumberStrictParse("123")); // true
console.log(isValidNumberStrictParse("3.14")); // true
console.log(isValidNumberStrictParse("-10")); // true
console.log(isValidNumberStrictParse("0")); // true
console.log(isValidNumberStrictParse(" 50 ")); // true (after trim)
console.log(isValidNumberStrictParse("1e5")); // true
console.log(isValidNumberStrictParse("abc")); // false
console.log(isValidNumberStrictParse("10px")); // false (String(10) !== "10px")
console.log(isValidNumberStrictParse("0.0")); // true
console.log(isValidNumberStrictParse(".5")); // false (String(0.5) !== ".5")
console.log(isValidNumberStrictParse("5.")); // false (String(5) !== "5.")
Using parseFloat()
and string comparison for strict validation.
parseFloat()
could successfully extract a number from the beginning of the string.