Skip to content

Commit 4da9278

Browse files
authored
fix: support nested object deconstructuring with type annotation (#4548)
1 parent 5b7d8df commit 4da9278

File tree

2 files changed

+82
-1
lines changed

2 files changed

+82
-1
lines changed

Diff for: packages/eslint-plugin/src/rules/typedef.ts

+24-1
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,25 @@ export default util.createRule<[Options], MessageIds>({
149149
);
150150
}
151151

152+
function isAncestorHasTypeAnnotation(
153+
node: TSESTree.ObjectPattern,
154+
): boolean {
155+
let ancestor = node.parent;
156+
157+
while (ancestor) {
158+
if (
159+
ancestor.type === AST_NODE_TYPES.ObjectPattern &&
160+
ancestor.typeAnnotation
161+
) {
162+
return true;
163+
}
164+
165+
ancestor = ancestor.parent;
166+
}
167+
168+
return false;
169+
}
170+
152171
return {
153172
...(arrayDestructuring && {
154173
ArrayPattern(node): void {
@@ -193,7 +212,11 @@ export default util.createRule<[Options], MessageIds>({
193212
}),
194213
...(objectDestructuring && {
195214
ObjectPattern(node): void {
196-
if (!node.typeAnnotation && !isForOfStatementContext(node)) {
215+
if (
216+
!node.typeAnnotation &&
217+
!isForOfStatementContext(node) &&
218+
!isAncestorHasTypeAnnotation(node)
219+
) {
197220
report(node);
198221
}
199222
},

Diff for: packages/eslint-plugin/tests/rules/typedef.test.ts

+58
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,26 @@ ruleTester.run('typedef', rule, {
201201
},
202202
],
203203
},
204+
{
205+
code: `
206+
const {
207+
id,
208+
details: {
209+
name: {
210+
first,
211+
middle,
212+
last,
213+
forTest: { moreNested },
214+
},
215+
},
216+
}: User = getUser();
217+
`,
218+
options: [
219+
{
220+
objectDestructuring: true,
221+
},
222+
],
223+
},
204224
// Function parameters
205225
'function receivesNumber(a: number): void {}',
206226
'function receivesStrings(a: string, b: string): void {}',
@@ -516,6 +536,44 @@ class ClassName {
516536
},
517537
],
518538
},
539+
{
540+
code: `
541+
const {
542+
id,
543+
details: {
544+
name: {
545+
first,
546+
middle,
547+
last,
548+
forTest: { moreNested },
549+
},
550+
},
551+
} = getUser();
552+
`,
553+
errors: [
554+
{
555+
data: { name: 'first' },
556+
messageId: 'expectedTypedef',
557+
},
558+
{
559+
data: { name: 'middle' },
560+
messageId: 'expectedTypedef',
561+
},
562+
{
563+
data: { name: 'last' },
564+
messageId: 'expectedTypedef',
565+
},
566+
{
567+
data: { name: 'moreNested' },
568+
messageId: 'expectedTypedef',
569+
},
570+
],
571+
options: [
572+
{
573+
objectDestructuring: true,
574+
},
575+
],
576+
},
519577
// Arrow parameters
520578
{
521579
code: 'const receivesNumber = (a): void => {};',

0 commit comments

Comments
 (0)