Skip to content

Commit 796032d

Browse files
authored
feat(eslint-plugin-query): enhance no-rest-destructuring rule to detect spread operations (#8802)
1 parent d7f4cb0 commit 796032d

File tree

2 files changed

+65
-3
lines changed

2 files changed

+65
-3
lines changed

packages/eslint-plugin-query/src/__tests__/no-rest-destructuring.test.ts

+25
Original file line numberDiff line numberDiff line change
@@ -365,5 +365,30 @@ ruleTester.run('no-rest-destructuring', rule, {
365365
`,
366366
errors: [{ messageId: 'objectRestDestructure' }],
367367
},
368+
{
369+
name: 'useQuery result is spread in return statement',
370+
code: normalizeIndent`
371+
import { useQuery } from '@tanstack/react-query'
372+
373+
function Component() {
374+
const query = useQuery()
375+
return { ...query, data: query.data[0] }
376+
}
377+
`,
378+
errors: [{ messageId: 'objectRestDestructure' }],
379+
},
380+
{
381+
name: 'useQuery result is spread in object expression',
382+
code: normalizeIndent`
383+
import { useQuery } from '@tanstack/react-query'
384+
385+
function Component() {
386+
const query = useQuery()
387+
const result = { ...query, data: query.data[0] }
388+
return result
389+
}
390+
`,
391+
errors: [{ messageId: 'objectRestDestructure' }],
392+
},
368393
],
369394
})

packages/eslint-plugin-query/src/rules/no-rest-destructuring/no-rest-destructuring.rule.ts

+40-3
Original file line numberDiff line numberDiff line change
@@ -34,33 +34,45 @@ export const rule = createRule({
3434
defaultOptions: [],
3535

3636
create: detectTanstackQueryImports((context, _, helpers) => {
37+
const queryResultVariables = new Set<string>()
38+
3739
return {
3840
CallExpression: (node) => {
3941
if (
4042
!ASTUtils.isIdentifierWithOneOfNames(node.callee, queryHooks) ||
41-
!helpers.isTanstackQueryImport(node.callee) ||
42-
node.parent.type !== AST_NODE_TYPES.VariableDeclarator
43+
node.parent.type !== AST_NODE_TYPES.VariableDeclarator ||
44+
!helpers.isTanstackQueryImport(node.callee)
4345
) {
4446
return
4547
}
4648

4749
const returnValue = node.parent.id
50+
4851
if (
4952
node.callee.name !== 'useQueries' &&
5053
node.callee.name !== 'useSuspenseQueries'
5154
) {
5255
if (NoRestDestructuringUtils.isObjectRestDestructuring(returnValue)) {
53-
context.report({
56+
return context.report({
5457
node: node.parent,
5558
messageId: 'objectRestDestructure',
5659
})
5760
}
61+
62+
if (returnValue.type === AST_NODE_TYPES.Identifier) {
63+
queryResultVariables.add(returnValue.name)
64+
}
65+
5866
return
5967
}
6068

6169
if (returnValue.type !== AST_NODE_TYPES.ArrayPattern) {
70+
if (returnValue.type === AST_NODE_TYPES.Identifier) {
71+
queryResultVariables.add(returnValue.name)
72+
}
6273
return
6374
}
75+
6476
returnValue.elements.forEach((queryResult) => {
6577
if (queryResult === null) {
6678
return
@@ -73,6 +85,31 @@ export const rule = createRule({
7385
}
7486
})
7587
},
88+
89+
VariableDeclarator: (node) => {
90+
if (
91+
node.init?.type === AST_NODE_TYPES.Identifier &&
92+
queryResultVariables.has(node.init.name) &&
93+
NoRestDestructuringUtils.isObjectRestDestructuring(node.id)
94+
) {
95+
context.report({
96+
node,
97+
messageId: 'objectRestDestructure',
98+
})
99+
}
100+
},
101+
102+
SpreadElement: (node) => {
103+
if (
104+
node.argument.type === AST_NODE_TYPES.Identifier &&
105+
queryResultVariables.has(node.argument.name)
106+
) {
107+
context.report({
108+
node,
109+
messageId: 'objectRestDestructure',
110+
})
111+
}
112+
},
76113
}
77114
}),
78115
})

0 commit comments

Comments
 (0)