Javascript

ESLint Unexpected use of isNaN

25 September 2026 · 5 min read

ESLint Unexpected use of isNaN

Navigating the intricacies of JavaScript development often involves ensuring code robustness and predictability. One common yet often misunderstood warning developers encounter is the “ESLint Unexpected use of isNaN” message. This warning signals a potential flaw in how you’re checking for “Not-a-Number” values, pointing towards a global function with known quirks. Understanding this linting error is crucial for writing cleaner, more reliable JavaScript. As an experienced developer, recognizing and rectifying this specific ESLint warning can significantly improve your application’s stability, preventing subtle bugs that might otherwise go unnoticed. This article will delve into why ESLint flags the traditional isNaN() function, explore the superior alternatives, and guide you through resolving these warnings to foster better code quality.

Understanding the Global isNaN() Pitfall

The global isNaN() function, a long-standing feature of JavaScript, is designed to determine if a value is NaN (Not-a-Number). However, its behavior is often surprising due to implicit type coercion. When you pass a non-number value to isNaN(), it first attempts to convert that value into a number. If this conversion results in NaN, then isNaN() returns true, leading to unexpected outcomes. For instance, isNaN('hello') returns true because Number('hello') results in NaN, which is not intuitive if you expect it to check if the original value literally is NaN.

This type coercion can mask logical errors, especially when dealing with user input or data from external APIs where types might not be strictly controlled. Consider a scenario where you expect a numeric string but receive an empty string or a non-numeric one. The global isNaN() would incorrectly report these as NaN, potentially bypassing validation checks. This behavior deviates from modern JavaScript’s emphasis on explicit type handling, leading to the “ESLint Unexpected use of isNaN” warning as a guardrail against these pitfalls. It’s precisely this ambiguity that ESLint aims to highlight, guiding developers towards more predictable validation methods.

The ECMAScript 6 (ES6) standard introduced Number.isNaN() to address these shortcomings. Unlike its global counterpart, Number.isNaN() does not perform any type coercion. It returns true only if the value passed to it is literally the NaN primitive value, and false otherwise. This makes it a far more reliable and predictable tool for number validation. Industry best practices now strongly advocate for the use of Number.isNaN() over the global isNaN() function to ensure robust code that behaves as expected, reducing the likelihood of hard-to-debug issues caused by implicit conversions.

Why ESLint Flags isNaN

ESLint is a powerful static analysis tool that helps developers identify and fix problematic patterns in JavaScript code. The “ESLint Unexpected use of isNaN” warning specifically targets the global isNaN() function due to its unreliable type coercion. ESLint’s goal is to enforce consistent coding styles and catch potential errors before they manifest at runtime. By flagging the global isNaN(), ESLint encourages the use of safer, more predictable alternatives like Number.isNaN(), which was introduced in ES6 to provide a more accurate check for the NaN value without any implicit type conversion.

When ESLint warns about the unexpected use of isNaN, it’s typically enforcing a rule designed to prevent common JavaScript pitfalls related to type coercion. This rule, often part of a recommended configuration or a custom setup, aims to improve code reliability. For example, if you use isNaN('123'), it returns false, which seems correct. However, isNaN('abc') returns true, which is also technically correct but misleading, as 'abc' is not the NaN value itself, but rather becomes NaN when coerced to a number. Number.isNaN('abc'), by contrast, correctly returns false, because 'abc' is not strictly equal to the NaN primitive.

The core reason for this ESLint warning is to steer developers away from potential bugs arising from the global isNaN()’s behavior. It promotes a defensive coding style where explicit type checks are preferred over implicit conversions. This helps in building more maintainable and less error-prone applications. By adopting Number.isNaN(), you ensure that your checks for NaN are precise, only returning true when the value is indeed the NaN primitive, thereby aligning with modern JavaScript best practices and enhancing overall code quality. This shift is vital for preventing subtle data validation issues in complex applications.

Resolving ESLint Unexpected use of isNaN Warnings

Resolving the “ESLint Unexpected use of isNaN” warnings primarily involves replacing instances of the global isNaN() with the more reliable Number.isNaN(). This simple change addresses the core issue of type coercion, ensuring your number validation checks are accurate and predictable. For example, if you have if (isNaN(myVariable)), you should refactor it to if (Number.isNaN(myVariable)). This direct substitution is the most straightforward solution and aligns with modern JavaScript standards, providing a robust check that only returns true if the value is strictly the NaN primitive.

Beyond direct replacement, consider the broader context of your validation. Sometimes, you might not just want to check for NaN, but also ensure a value is a finite number. In such cases, Number.isFinite() can be an excellent alternative. For instance, if you’re expecting a valid, non-infinite number, Number.isFinite(value) returns true only if the value is a number and not NaN, Infinity, or -Infinity. This method provides a comprehensive check for valid numeric values. Additionally, combining typeof checks can offer even greater precision, especially when dealing with mixed data types from external sources.

Here are the steps to effectively refactor your code and resolve these ESLint warnings:

  1. Identify all occurrences: Use your IDE’s search function to find every instance of isNaN( in your codebase.

  2. Analyze context: For each instance, determine if you truly need to check for the NaN primitive or if you’re trying to validate if a value is generally a number.

  3. Replace with Number.isNaN(): If you strictly need to check for the NaN primitive, replace isNaN(value) with Question & Answer :
    I’m trying to use the isNaN global function inside an arrow function in a Node.js module but I’m getting this error:

    [eslint] Unexpected use of 'isNaN'. (no-restricted-globals)

    This is my code:

    const isNumber = value => !isNaN(parseFloat(value)); module.exports = { isNumber, }; 
    

    Any idea on what am I doing wrong?

    PS: I’m using the AirBnB style guide.

    As the documentation suggests, use Number.isNaN.

    const isNumber = value => !Number.isNaN(Number(value)); 
    

    Quoting Airbnb’s documentation:

    Why? The global isNaN coerces non-numbers to numbers, returning true for anything that coerces to NaN. If this behavior is desired, make it explicit.

    // bad isNaN('1.2'); // false isNaN('1.2.3'); // true // good Number.isNaN('1.2.3'); // false Number.isNaN(Number('1.2.3')); // true