Skip to content

Commit c402a2b

Browse files
Eliya Cohenautofix-ci[bot]
andauthored
fix(eslint-plugin-query): handle optional and non-null chaining in exhaustive-deps (#8365)
* fix: handle optional and non-null chaining in exhaustive-deps Fixed a false positive in the exhaustive-deps rule when using optional chaining and non-null assertions in query keys and functions. * ci: apply automated fixes --------- Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
1 parent dc4ae50 commit c402a2b

File tree

3 files changed

+39
-2
lines changed

3 files changed

+39
-2
lines changed

packages/eslint-plugin-query/src/__tests__/exhaustive-deps.test.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -473,6 +473,30 @@ ruleTester.run('exhaustive-deps', rule, {
473473
};
474474
`,
475475
},
476+
{
477+
name: 'should pass with optional chaining as key',
478+
code: `
479+
function useTest(data?: any) {
480+
return useQuery({
481+
queryKey: ['query-name', data?.address],
482+
queryFn: async () => sendQuery(data.address),
483+
enabled: !!data?.address,
484+
})
485+
}
486+
`,
487+
},
488+
{
489+
name: 'should pass with optional chaining as key and non-null assertion in queryFn',
490+
code: `
491+
function useTest(data?: any) {
492+
return useQuery({
493+
queryKey: ['query-name', data?.address],
494+
queryFn: async () => sendQuery(data!.address),
495+
enabled: !!data?.address,
496+
})
497+
}
498+
`,
499+
},
476500
],
477501
invalid: [
478502
{

packages/eslint-plugin-query/src/rules/exhaustive-deps/exhaustive-deps.rule.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,13 +102,16 @@ export const rule = createRule({
102102

103103
const existingKeys = ASTUtils.getNestedIdentifiers(queryKeyNode).map(
104104
(identifier) =>
105-
ASTUtils.mapKeyNodeToText(identifier, context.sourceCode),
105+
ASTUtils.mapKeyNodeToBaseText(identifier, context.sourceCode),
106106
)
107107

108108
const missingRefs = relevantRefs
109109
.map((ref) => ({
110110
ref: ref,
111-
text: ASTUtils.mapKeyNodeToText(ref.identifier, context.sourceCode),
111+
text: ASTUtils.mapKeyNodeToBaseText(
112+
ref.identifier,
113+
context.sourceCode,
114+
),
112115
}))
113116
.filter(({ ref, text }) => {
114117
return (

packages/eslint-plugin-query/src/utils/ast-utils.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,10 +224,20 @@ export const ASTUtils = {
224224
return sourceCode.getText(
225225
ASTUtils.traverseUpOnly(node, [
226226
AST_NODE_TYPES.MemberExpression,
227+
AST_NODE_TYPES.TSNonNullExpression,
227228
AST_NODE_TYPES.Identifier,
228229
]),
229230
)
230231
},
232+
mapKeyNodeToBaseText(
233+
node: TSESTree.Node,
234+
sourceCode: Readonly<TSESLint.SourceCode>,
235+
) {
236+
return ASTUtils.mapKeyNodeToText(node, sourceCode).replace(
237+
/(\?\.|!\.)/g,
238+
'.',
239+
)
240+
},
231241
isValidReactComponentOrHookName(
232242
identifier: TSESTree.Identifier | null | undefined,
233243
) {

0 commit comments

Comments
 (0)