From a1433ca0bacff76f720ffec9a0020f56e8c9ffed Mon Sep 17 00:00:00 2001 From: StyleShit <32631382+StyleShit@users.noreply.github.com> Date: Thu, 1 Feb 2024 21:30:17 +0200 Subject: [PATCH] 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 --- .../__tests__/ESLintRuleExhaustiveDeps-test.js | 18 ++++++++++++++++++ .../src/ExhaustiveDeps.js | 13 +++++++++++-- 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/packages/eslint-plugin-react-hooks/__tests__/ESLintRuleExhaustiveDeps-test.js b/packages/eslint-plugin-react-hooks/__tests__/ESLintRuleExhaustiveDeps-test.js index eb58f8d4d1fbe..7f545540acf90 100644 --- a/packages/eslint-plugin-react-hooks/__tests__/ESLintRuleExhaustiveDeps-test.js +++ b/packages/eslint-plugin-react-hooks/__tests__/ESLintRuleExhaustiveDeps-test.js @@ -7747,6 +7747,24 @@ const testsTypescript = { } `, }, + { + code: normalizeIndent` + function App(props) { + React.useEffect(() => { + console.log(props.test); + }, [props.test] as const); + } + `, + }, + { + code: normalizeIndent` + function App(props) { + React.useEffect(() => { + console.log(props.test); + }, [props.test] as any); + } + `, + }, ], invalid: [ { diff --git a/packages/eslint-plugin-react-hooks/src/ExhaustiveDeps.js b/packages/eslint-plugin-react-hooks/src/ExhaustiveDeps.js index 62a451377f6e6..e32a2c7a111b3 100644 --- a/packages/eslint-plugin-react-hooks/src/ExhaustiveDeps.js +++ b/packages/eslint-plugin-react-hooks/src/ExhaustiveDeps.js @@ -618,7 +618,12 @@ export default { const declaredDependencies = []; const externalDependencies = new Set(); - if (declaredDependenciesNode.type !== 'ArrayExpression') { + const isArrayExpression = + declaredDependenciesNode.type === 'ArrayExpression'; + const isTSAsArrayExpression = + declaredDependenciesNode.type === 'TSAsExpression' && + declaredDependenciesNode.expression.type === 'ArrayExpression'; + if (!isArrayExpression && !isTSAsArrayExpression) { // If the declared dependencies are not an array expression then we // can't verify that the user provided the correct dependencies. Tell // the user this in an error. @@ -631,7 +636,11 @@ export default { 'dependencies.', }); } else { - declaredDependenciesNode.elements.forEach(declaredDependencyNode => { + const arrayExpression = isTSAsArrayExpression + ? declaredDependenciesNode.expression + : declaredDependenciesNode; + + arrayExpression.elements.forEach(declaredDependencyNode => { // Skip elided elements. if (declaredDependencyNode === null) { return;