Skip to content

Commit d13e4b5

Browse files
committed
1 parent 3a1967b commit d13e4b5

File tree

2 files changed

+64
-4
lines changed

2 files changed

+64
-4
lines changed

packages/eslint-plugin-react-hooks/__tests__/ESLintRuleExhaustiveDeps-test.js

+46
Original file line numberDiff line numberDiff line change
@@ -7738,6 +7738,18 @@ const testsTypescript = {
77387738
}
77397739
`,
77407740
},
7741+
{
7742+
code: normalizeIndent`
7743+
function MyComponent() {
7744+
const [foo, setFoo] = useState<{ bar: { b: number } }>({ bar: { b: 42 } });
7745+
7746+
useEffect(() => {
7747+
const square = (x: typeof foo.bar.b) => x * x;
7748+
setFoo((previous) => ({ ...previous, bar: { b: square(previous.bar.b) } }));
7749+
}, []);
7750+
}
7751+
`,
7752+
},
77417753
],
77427754
invalid: [
77437755
{
@@ -8091,6 +8103,40 @@ const testsTypescript = {
80918103
},
80928104
],
80938105
},
8106+
{
8107+
code: normalizeIndent`
8108+
function MyComponent() {
8109+
const [foo, setFoo] = useState<{ bar: { b: number } }>({ bar: { b: 42 } });
8110+
8111+
useEffect(() => {
8112+
const square = () => foo.bar.b * foo.bar.b;
8113+
setFoo((previous) => ({ ...previous, bar: { b: square() } }));
8114+
}, []);
8115+
}
8116+
`,
8117+
errors: [
8118+
{
8119+
message:
8120+
"React Hook useEffect has a missing dependency: 'foo.bar.b'. " +
8121+
'Either include it or remove the dependency array.',
8122+
suggestions: [
8123+
{
8124+
desc: 'Update the dependencies array to be: [foo.bar.b]',
8125+
output: normalizeIndent`
8126+
function MyComponent() {
8127+
const [foo, setFoo] = useState<{ bar: { b: number } }>({ bar: { b: 42 } });
8128+
8129+
useEffect(() => {
8130+
const square = () => foo.bar.b * foo.bar.b;
8131+
setFoo((previous) => ({ ...previous, bar: { b: square() } }));
8132+
}, [foo.bar.b]);
8133+
}
8134+
`,
8135+
},
8136+
],
8137+
},
8138+
],
8139+
},
80948140
],
80958141
};
80968142

packages/eslint-plugin-react-hooks/src/ExhaustiveDeps.js

+18-4
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,23 @@ export default {
8787
return result;
8888
};
8989
}
90+
function checkTypeOfParent(dependencyNode) {
91+
let currentNode = dependencyNode.parent;
92+
let foundMatch = false;
93+
94+
while (currentNode) {
95+
if (
96+
currentNode.type === 'TSTypeQuery' ||
97+
currentNode.type === 'TSTypeReference'
98+
) {
99+
foundMatch = true;
100+
break;
101+
}
102+
currentNode = currentNode.parent;
103+
}
104+
105+
return foundMatch;
106+
}
90107
/**
91108
* Visitor for both function expressions and arrow function expressions.
92109
*/
@@ -431,10 +448,7 @@ export default {
431448
});
432449
}
433450

434-
if (
435-
dependencyNode.parent.type === 'TSTypeQuery' ||
436-
dependencyNode.parent.type === 'TSTypeReference'
437-
) {
451+
if (checkTypeOfParent(dependencyNode)) {
438452
continue;
439453
}
440454

0 commit comments

Comments
 (0)