Skip to content

Commit

Permalink
fix(eslint-plugin): [typedef] allow array/object destructuring in for/of
Browse files Browse the repository at this point in the history
  • Loading branch information
a-tarasyuk committed Feb 5, 2020
1 parent 10d86b1 commit 0f39133
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 2 deletions.
6 changes: 6 additions & 0 deletions packages/eslint-plugin/docs/rules/typedef.md
Expand Up @@ -76,6 +76,9 @@ Examples of **correct** code with `{ "arrayDestructuring": true }`:
const [a]: number[] = [1];
const [b]: [number] = [2];
const [c, d]: [boolean, string] = [true, 'text'];

for (const [key, val] of new Map([['key', 1]])) {
}
```

### `arrowParameter`
Expand Down Expand Up @@ -144,6 +147,9 @@ Examples of **correct** code with `{ "objectDestructuring": true }`:
```ts
const { length }: { length: number } = 'text';
const [b, c]: [number, number] = Math.random() ? [1, 2] : [3, 4];

for (const { key, val } of [{ key: 'key', val: 1 }]) {
}
```

### `parameter`
Expand Down
32 changes: 30 additions & 2 deletions packages/eslint-plugin/src/rules/typedef.ts
Expand Up @@ -69,6 +69,26 @@ export default util.createRule<[Options], MessageIds>({
return node.type === AST_NODE_TYPES.Identifier ? node.name : undefined;
}

function isForOfStatementContext(
node: TSESTree.ArrayPattern | TSESTree.ObjectPattern,
): boolean {
let current: TSESTree.Node | undefined = node.parent;
while (current) {
if (
current.type === AST_NODE_TYPES.VariableDeclarator ||
current.type === AST_NODE_TYPES.VariableDeclaration
) {
current = current.parent;
} else if (current.type === AST_NODE_TYPES.ForOfStatement) {
return true;
} else {
break;
}
}

return false;
}

function checkParameters(params: TSESTree.Parameter[]): void {
for (const param of params) {
let annotationNode: TSESTree.Node | undefined;
Expand Down Expand Up @@ -102,7 +122,11 @@ export default util.createRule<[Options], MessageIds>({

return {
ArrayPattern(node): void {
if (options[OptionKeys.ArrayDestructuring] && !node.typeAnnotation) {
if (
options[OptionKeys.ArrayDestructuring] &&
!node.typeAnnotation &&
!isForOfStatementContext(node)
) {
report(node);
}
},
Expand Down Expand Up @@ -132,7 +156,11 @@ export default util.createRule<[Options], MessageIds>({
}
},
ObjectPattern(node): void {
if (options[OptionKeys.ObjectDestructuring] && !node.typeAnnotation) {
if (
options[OptionKeys.ObjectDestructuring] &&
!node.typeAnnotation &&
!isForOfStatementContext(node)
) {
report(node);
}
},
Expand Down
16 changes: 16 additions & 0 deletions packages/eslint-plugin/tests/rules/typedef.test.ts
Expand Up @@ -38,6 +38,14 @@ ruleTester.run('typedef', rule, {
},
],
},
{
code: `for (const [key, val] of new Map([['key', 1]])) {}`,
options: [
{
arrayDestructuring: true,
},
],
},
`let a: number;
[a] = [1];`,
// Arrow parameters
Expand Down Expand Up @@ -101,6 +109,14 @@ ruleTester.run('typedef', rule, {
},
],
},
{
code: `for (const { key, val } of [{ key: 'key', val: 1 }]) {}`,
options: [
{
objectDestructuring: true,
},
],
},
// Function parameters
`function receivesNumber(a: number): void { }`,
`function receivesStrings(a: string, b: string): void { }`,
Expand Down

0 comments on commit 0f39133

Please sign in to comment.