diff --git a/.changeset/fix-no-unstable-deps-prototype-lookups.md b/.changeset/fix-no-unstable-deps-prototype-lookups.md new file mode 100644 index 00000000000..f1d8870ea1d --- /dev/null +++ b/.changeset/fix-no-unstable-deps-prototype-lookups.md @@ -0,0 +1,5 @@ +--- +'@tanstack/eslint-plugin-query': patch +--- + +Fix false-positive warnings in `no-unstable-deps` rule caused by `Object.prototype` property lookups (`toString`, `valueOf`, etc.). diff --git a/packages/eslint-plugin-query/src/__tests__/no-unstable-deps.test.ts b/packages/eslint-plugin-query/src/__tests__/no-unstable-deps.test.ts index fca18c41cd2..8d41ac08659 100644 --- a/packages/eslint-plugin-query/src/__tests__/no-unstable-deps.test.ts +++ b/packages/eslint-plugin-query/src/__tests__/no-unstable-deps.test.ts @@ -128,6 +128,55 @@ const baseTestCases = { } `, }, + { + name: `should pass when functions or variables with Object.prototype names are used with ${reactHookAlias}`, + code: ` + ${reactHookImport} + import { useQuery } from "@tanstack/react-query"; + + function Component() { + const toString = () => 'str'; + const valueOf = 42; + const callback = ${reactHookInvocation}(() => { toString() }, [toString, valueOf]); + return; + } + `, + }, + { + name: `should pass when custom functions named after Object.prototype methods are invoked`, + code: ` + ${reactHookImport} + import { useQuery } from "@tanstack/react-query"; + + function toString() { + return 'test'; + } + + function Component() { + const res = toString(); + const callback = ${reactHookInvocation}(() => { res }, [res]); + return; + } + `, + }, + { + name: `should pass when a local function named after Object.prototype method is called alongside destructured query result with ${reactHookAlias}`, + code: ` + ${reactHookImport} + import { useQuery } from "@tanstack/react-query"; + + function toString() { + return 'formatted'; + } + + function Component() { + const { data } = useQuery({ queryKey: ['test'], queryFn: () => 'test' }); + const formatted = toString(); + const callback = ${reactHookInvocation}(() => { formatted }, [data, formatted]); + return; + } + `, + }, ]), invalid: ({ reactHookImport, diff --git a/packages/eslint-plugin-query/src/rules/no-unstable-deps/no-unstable-deps.rule.ts b/packages/eslint-plugin-query/src/rules/no-unstable-deps/no-unstable-deps.rule.ts index 934773faa0f..e646f268d75 100644 --- a/packages/eslint-plugin-query/src/rules/no-unstable-deps/no-unstable-deps.rule.ts +++ b/packages/eslint-plugin-query/src/rules/no-unstable-deps/no-unstable-deps.rule.ts @@ -35,9 +35,9 @@ export const rule = createRule({ defaultOptions: [], create: detectTanstackQueryImports((context, _options, helpers) => { - const trackedVariables: Record = {} - const trackedCustomHooks: Record = {} - const hookAliasMap: Record = {} + const trackedVariables: Record = Object.create(null) + const trackedCustomHooks: Record = Object.create(null) + const hookAliasMap: Record = Object.create(null) const pendingVariableDeclarators: Array = [] const pendingDependencyChecks: Array<{ reactHook: string