@@ -14,6 +14,7 @@ export type Options = [
14
14
argsIgnorePattern ?: string ;
15
15
caughtErrors ?: 'all' | 'none' ;
16
16
caughtErrorsIgnorePattern ?: string ;
17
+ destructuredArrayIgnorePattern ?: string ;
17
18
} ,
18
19
] ;
19
20
@@ -25,6 +26,7 @@ interface TranslatedOptions {
25
26
argsIgnorePattern ?: RegExp ;
26
27
caughtErrors : 'all' | 'none' ;
27
28
caughtErrorsIgnorePattern ?: RegExp ;
29
+ destructuredArrayIgnorePattern ?: RegExp ;
28
30
}
29
31
30
32
export default util . createRule < Options , MessageIds > ( {
@@ -66,6 +68,9 @@ export default util.createRule<Options, MessageIds>({
66
68
caughtErrorsIgnorePattern : {
67
69
type : 'string' ,
68
70
} ,
71
+ destructuredArrayIgnorePattern : {
72
+ type : 'string' ,
73
+ } ,
69
74
} ,
70
75
additionalProperties : false ,
71
76
} ,
@@ -123,12 +128,33 @@ export default util.createRule<Options, MessageIds>({
123
128
'u' ,
124
129
) ;
125
130
}
131
+
132
+ if ( firstOption . destructuredArrayIgnorePattern ) {
133
+ options . destructuredArrayIgnorePattern = new RegExp (
134
+ firstOption . destructuredArrayIgnorePattern ,
135
+ 'u' ,
136
+ ) ;
137
+ }
126
138
}
127
139
}
128
140
return options ;
129
141
} ) ( ) ;
130
142
131
143
function collectUnusedVariables ( ) : TSESLint . Scope . Variable [ ] {
144
+ /**
145
+ * Checks whether a node is a sibling of the rest property or not.
146
+ * @param {ASTNode } node a node to check
147
+ * @returns {boolean } True if the node is a sibling of the rest property, otherwise false.
148
+ */
149
+ function hasRestSibling ( node : TSESTree . Node ) : boolean {
150
+ return (
151
+ node . type === AST_NODE_TYPES . Property &&
152
+ node . parent ?. type === AST_NODE_TYPES . ObjectPattern &&
153
+ node . parent . properties [ node . parent . properties . length - 1 ] . type ===
154
+ AST_NODE_TYPES . RestElement
155
+ ) ;
156
+ }
157
+
132
158
/**
133
159
* Determines if a variable has a sibling rest property
134
160
* @param variable eslint-scope variable object.
@@ -138,17 +164,14 @@ export default util.createRule<Options, MessageIds>({
138
164
variable : TSESLint . Scope . Variable ,
139
165
) : boolean {
140
166
if ( options . ignoreRestSiblings ) {
141
- return variable . defs . some ( def => {
142
- const propertyNode = def . name . parent ! ;
143
- const patternNode = propertyNode . parent ! ;
144
-
145
- return (
146
- propertyNode . type === AST_NODE_TYPES . Property &&
147
- patternNode . type === AST_NODE_TYPES . ObjectPattern &&
148
- patternNode . properties [ patternNode . properties . length - 1 ] . type ===
149
- AST_NODE_TYPES . RestElement
150
- ) ;
151
- } ) ;
167
+ const hasRestSiblingDefinition = variable . defs . some ( def =>
168
+ hasRestSibling ( def . name . parent ! ) ,
169
+ ) ;
170
+ const hasRestSiblingReference = variable . references . some ( ref =>
171
+ hasRestSibling ( ref . identifier . parent ! ) ,
172
+ ) ;
173
+
174
+ return hasRestSiblingDefinition || hasRestSiblingReference ;
152
175
}
153
176
154
177
return false ;
@@ -188,6 +211,20 @@ export default util.createRule<Options, MessageIds>({
188
211
continue ;
189
212
}
190
213
214
+ const refUsedInArrayPatterns = variable . references . some (
215
+ ref => ref . identifier . parent ?. type === AST_NODE_TYPES . ArrayPattern ,
216
+ ) ;
217
+
218
+ // skip elements of array destructuring patterns
219
+ if (
220
+ ( def . name . parent ?. type === AST_NODE_TYPES . ArrayPattern ||
221
+ refUsedInArrayPatterns ) &&
222
+ 'name' in def . name &&
223
+ options . destructuredArrayIgnorePattern ?. test ( def . name . name )
224
+ ) {
225
+ continue ;
226
+ }
227
+
191
228
// skip catch variables
192
229
if ( def . type === TSESLint . Scope . DefinitionType . CatchClause ) {
193
230
if ( options . caughtErrors === 'none' ) {
@@ -361,9 +398,17 @@ export default util.createRule<Options, MessageIds>({
361
398
function getAssignedMessageData (
362
399
unusedVar : TSESLint . Scope . Variable ,
363
400
) : Record < string , unknown > {
364
- const additional = options . varsIgnorePattern
365
- ? `. Allowed unused vars must match ${ options . varsIgnorePattern . toString ( ) } `
366
- : '' ;
401
+ const def = unusedVar . defs [ 0 ] ;
402
+ let additional = '' ;
403
+
404
+ if (
405
+ options . destructuredArrayIgnorePattern &&
406
+ def ?. name . parent ?. type === AST_NODE_TYPES . ArrayPattern
407
+ ) {
408
+ additional = `. Allowed unused elements of array destructuring patterns must match ${ options . destructuredArrayIgnorePattern . toString ( ) } ` ;
409
+ } else if ( options . varsIgnorePattern ) {
410
+ additional = `. Allowed unused vars must match ${ options . varsIgnorePattern . toString ( ) } ` ;
411
+ }
367
412
368
413
return {
369
414
varName : unusedVar . name ,
0 commit comments