diff --git a/eslint-factory/src/rules/prefer-number-isnan.test.ts b/eslint-factory/src/rules/prefer-number-isnan.test.ts index 080aef770fe..e27bbb0fbde 100644 --- a/eslint-factory/src/rules/prefer-number-isnan.test.ts +++ b/eslint-factory/src/rules/prefer-number-isnan.test.ts @@ -34,9 +34,13 @@ describe("prefer-number-isnan", () => { valid: [ `function isNaN(value) { return false; } isNaN(value);`, `const isNaN = Number.isNaN; isNaN(value);`, + `import { isNaN } from "lodash"; isNaN(value);`, `const globalThis = { isNaN(value) { return value; } }; globalThis.isNaN(value);`, `const window = { isNaN(value) { return value; } }; window["isNaN"](value);`, `const global = { isNaN(value) { return value; } }; global.isNaN(value);`, + `import { globalThis } from "./global-shim"; globalThis.isNaN(value);`, + `import { window } from "./browser-shim"; window.isNaN(value);`, + `import { global } from "./server-shim"; global["isNaN"](value);`, // Dynamic computed access — identifier property reference, not string literal "isNaN" `globalThis[isNaN](value);`, ], @@ -99,4 +103,20 @@ describe("prefer-number-isnan", () => { ], }); }); + + it("invalid: global isNaN() is still flagged in ESM mode without a shadow", () => { + esmRuleTester.run("prefer-number-isnan", preferNumberIsNanRule, { + valid: [], + invalid: [ + { + code: `isNaN(value);`, + errors: [{ messageId: "preferNumberIsNaN", suggestions: [{ messageId: "replaceWithNumberIsNaN", output: `Number.isNaN(value);` }] }], + }, + { + code: `window.isNaN(value);`, + errors: [{ messageId: "preferNumberIsNaN", suggestions: [{ messageId: "replaceWithNumberIsNaN", output: `Number.isNaN(value);` }] }], + }, + ], + }); + }); }); diff --git a/eslint-factory/src/rules/prefer-number-isnan.ts b/eslint-factory/src/rules/prefer-number-isnan.ts index d6e55111379..0589239b1d1 100644 --- a/eslint-factory/src/rules/prefer-number-isnan.ts +++ b/eslint-factory/src/rules/prefer-number-isnan.ts @@ -34,7 +34,8 @@ export const preferNumberIsNanRule = createRule({ while (scope) { const variable = scope.set.get(name); - if (variable?.defs.some(d => d.type !== "ImportBinding")) { + // Any local definition shadows the global (including ESM ImportBinding). + if (variable && variable.defs.length > 0) { return true; }