fix(eslint-plugin-react-hooks): accepting `as` expressions as deps array (#28189)
## Summary This PR closes #25844 The original issue talks about `as const`, but seems like it fails for any `as X` expressions since it adds another nesting level to the AST. EDIT: Also closes #20162 ## How did you test this change? Added unit tests
StyleShit committed
Feb 1, 2024 at 21:30 UTC
a1433ca0bacff76f720ffec9a0020f56e8c9ffed
2 files changed
+29
-2
packages/eslint-plugin-react-hooks/__tests__/ESLintRuleExhaustiveDeps-test.js
+18
@@ -7747,6 +7747,24 @@ const testsTypescript = {
7747
}
7748
`,
7749
},
7750
+ {
7751
+ code: normalizeIndent`
7752
+ function App(props) {
7753
+ React.useEffect(() => {
7754
+ console.log(props.test);
7755
+ }, [props.test] as const);
7756
+ }
7757
+ `,
7758
+ },
7759
+ {
7760
+ code: normalizeIndent`
7761
+ function App(props) {
7762
+ React.useEffect(() => {
7763
+ console.log(props.test);
7764
+ }, [props.test] as any);
7765
+ }
7766
+ `,
7767
+ },
7768
],
7769
invalid: [
7770
{
packages/eslint-plugin-react-hooks/src/ExhaustiveDeps.js
+11
-2
@@ -618,7 +618,12 @@ export default {
618
619
const declaredDependencies = [];
620
const externalDependencies = new Set();
621
- if (declaredDependenciesNode.type !== 'ArrayExpression') {
621
+ const isArrayExpression =
622
+ declaredDependenciesNode.type === 'ArrayExpression';
623
+ const isTSAsArrayExpression =
624
+ declaredDependenciesNode.type === 'TSAsExpression' &&
625
+ declaredDependenciesNode.expression.type === 'ArrayExpression';
626
+ if (!isArrayExpression && !isTSAsArrayExpression) {
627
// If the declared dependencies are not an array expression then we
628
// can't verify that the user provided the correct dependencies. Tell
629
// the user this in an error.
@@ -631,7 +636,11 @@ export default {
636
'dependencies.',
637
});
638
} else {
634
- declaredDependenciesNode.elements.forEach(declaredDependencyNode => {
639
+ const arrayExpression = isTSAsArrayExpression
640
+ ? declaredDependenciesNode.expression
641
+ : declaredDependenciesNode;
642
+
643
+ arrayExpression.elements.forEach(declaredDependencyNode => {
644
// Skip elided elements.
645
if (declaredDependencyNode === null) {
646
return;