From ca980186b06182c19159f447749c87bf65db9d92 Mon Sep 17 00:00:00 2001 From: Pete Gonzalez <4673363+octogonz@users.noreply.github.com> Date: Wed, 31 Jul 2019 18:02:03 -0700 Subject: [PATCH] fix(eslint-plugin): [typedef] fix "variableDeclaration" to work with "for..in" and "for..of" --- packages/eslint-plugin/src/rules/typedef.ts | 27 ++++++++++++++++++- .../eslint-plugin/tests/rules/typedef.test.ts | 25 +++++++++++++++++ 2 files changed, 51 insertions(+), 1 deletion(-) diff --git a/packages/eslint-plugin/src/rules/typedef.ts b/packages/eslint-plugin/src/rules/typedef.ts index 5e0465e0e23..aad11bc5924 100644 --- a/packages/eslint-plugin/src/rules/typedef.ts +++ b/packages/eslint-plugin/src/rules/typedef.ts @@ -131,7 +131,32 @@ export default util.createRule<[Options], MessageIds>({ options[OptionKeys.VariableDeclaration] && !node.id.typeAnnotation ) { - report(node, getNodeName(node.id)); + // Are we inside a context that does not allow type annotations? + let typeAnnotationRequired = true; + + let current: TSESTree.Node | undefined = node.parent; + while (current) { + switch (current.type) { + case AST_NODE_TYPES.VariableDeclaration: + // Keep looking upwards + current = current.parent; + break; + case AST_NODE_TYPES.ForOfStatement: + case AST_NODE_TYPES.ForInStatement: + // Stop traversing and don't report an error + typeAnnotationRequired = false; + current = undefined; + break; + default: + // Stop traversing + current = undefined; + break; + } + } + + if (typeAnnotationRequired) { + report(node, getNodeName(node.id)); + } } }, }; diff --git a/packages/eslint-plugin/tests/rules/typedef.test.ts b/packages/eslint-plugin/tests/rules/typedef.test.ts index 8c281fe5e39..272d4f2ec19 100644 --- a/packages/eslint-plugin/tests/rules/typedef.test.ts +++ b/packages/eslint-plugin/tests/rules/typedef.test.ts @@ -190,6 +190,31 @@ ruleTester.run('typedef', rule, { }, ], }, + // Contexts where TypeScript doesn't allow annotations + { + code: `for (x of [1, 2, 3]) { }`, + options: [ + { + variableDeclaration: true, + }, + ], + }, + { + code: `for (const x in {}) { }`, + options: [ + { + variableDeclaration: true, + }, + ], + }, + { + code: `try { } catch (e) { }`, + options: [ + { + variableDeclaration: true, + }, + ], + }, ], invalid: [ // Array destructuring