eslint-config-typed 4.9.1 → 4.9.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"check-destructuring-completeness.d.mts","sourceRoot":"","sources":["../../../../src/plugins/ts-restrictions/rules/check-destructuring-completeness.mts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,QAAQ,EAEd,MAAM,0BAA0B,CAAC;AAGlC,KAAK,OAAO,GAAG,SAAS;IACtB,QAAQ,CAAC;QACP,8BAA8B,CAAC,EAAE,OAAO,CAAC;QACzC,gBAAgB,CAAC,EAAE,MAAM,CAAC;KAC3B,CAAC,CAAC;CACJ,CAAC;AAEF,KAAK,UAAU,GAAG,yBAAyB,CAAC;AAI5C,eAAO,MAAM,8BAA8B,EAAE,QAAQ,CAAC,UAAU,CAC9D,UAAU,EACV,OAAO,CAmPC,CAAC"}
1
+ {"version":3,"file":"check-destructuring-completeness.d.mts","sourceRoot":"","sources":["../../../../src/plugins/ts-restrictions/rules/check-destructuring-completeness.mts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,QAAQ,EAEd,MAAM,0BAA0B,CAAC;AAGlC,KAAK,OAAO,GAAG,SAAS;IACtB,QAAQ,CAAC;QACP,8BAA8B,CAAC,EAAE,OAAO,CAAC;QACzC,gBAAgB,CAAC,EAAE,MAAM,CAAC;KAC3B,CAAC,CAAC;CACJ,CAAC;AAEF,KAAK,UAAU,GAAG,yBAAyB,CAAC;AAI5C,eAAO,MAAM,8BAA8B,EAAE,QAAQ,CAAC,UAAU,CAC9D,UAAU,EACV,OAAO,CAwMC,CAAC"}
@@ -90,38 +90,27 @@ const checkDestructuringCompleteness = {
90
90
  }
91
91
  return false;
92
92
  };
93
- const checkNode = (node) => {
94
- if (node.id.type !== AST_NODE_TYPES.ObjectPattern)
95
- return;
96
- // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
97
- if (node.init === undefined || node.init === null)
98
- return;
99
- const shouldCheck = hasDirectiveComment(node) || isReactComponentPropsDestructuring(node);
100
- if (!shouldCheck)
101
- return;
102
- // If rest element is used, skip completeness check
103
- const hasRestElement = node.id.properties.some((prop) => prop.type === AST_NODE_TYPES.RestElement);
93
+ const checkObjectPatternCompleteness = (objectPattern, tsSourceNode) => {
94
+ const hasRestElement = objectPattern.properties.some((prop) => prop.type === AST_NODE_TYPES.RestElement);
104
95
  if (hasRestElement)
105
96
  return;
106
97
  // eslint-disable-next-line total-functions/no-unsafe-type-assertion
107
- const tsNode = esTreeNodeToTSNodeMap.get(node.init);
98
+ const tsNode = esTreeNodeToTSNodeMap.get(tsSourceNode);
108
99
  // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
109
100
  if (tsNode === undefined)
110
101
  return;
111
102
  const type = typeChecker.getTypeAtLocation(tsNode);
112
103
  const objectProps = getObjectTypeProperties(type);
113
- const mut_destructuredProps = new Set();
114
- for (const prop of node.id.properties) {
115
- if (prop.type === AST_NODE_TYPES.Property &&
116
- prop.key.type === AST_NODE_TYPES.Identifier) {
117
- mut_destructuredProps.add(prop.key.name);
118
- }
119
- }
120
- const missingProps = objectProps.filter((prop) => !mut_destructuredProps.has(prop));
104
+ const collected = collectDestructuredPropNames(objectPattern.properties);
105
+ // Dynamic computed properties cannot be resolved statically,
106
+ // so skip completeness check when they are present.
107
+ if (collected.hasDynamicComputedKey)
108
+ return;
109
+ const missingProps = objectProps.filter((prop) => !collected.names.has(prop));
121
110
  if (missingProps.length > 0) {
122
111
  context.report({
123
112
  // eslint-disable-next-line total-functions/no-unsafe-type-assertion
124
- node: node.id,
113
+ node: objectPattern,
125
114
  messageId: 'incompleteDestructuring',
126
115
  data: {
127
116
  missingProps: missingProps.join(', '),
@@ -130,7 +119,17 @@ const checkDestructuringCompleteness = {
130
119
  }
131
120
  };
132
121
  return {
133
- VariableDeclarator: checkNode,
122
+ VariableDeclarator: (node) => {
123
+ if (node.id.type !== AST_NODE_TYPES.ObjectPattern)
124
+ return;
125
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
126
+ if (node.init === undefined || node.init === null)
127
+ return;
128
+ const shouldCheck = hasDirectiveComment(node) || isReactComponentPropsDestructuring(node);
129
+ if (!shouldCheck)
130
+ return;
131
+ checkObjectPatternCompleteness(node.id, node.init);
132
+ },
134
133
  ArrowFunctionExpression: (node) => {
135
134
  if (!alwaysCheckReactComponentProps)
136
135
  return;
@@ -138,34 +137,7 @@ const checkDestructuringCompleteness = {
138
137
  return;
139
138
  for (const param of node.params) {
140
139
  if (param.type === AST_NODE_TYPES.ObjectPattern) {
141
- // If rest element is used, skip completeness check
142
- const hasRestElement = param.properties.some((prop) => prop.type === AST_NODE_TYPES.RestElement);
143
- if (hasRestElement)
144
- continue;
145
- // eslint-disable-next-line total-functions/no-unsafe-type-assertion
146
- const tsNode = esTreeNodeToTSNodeMap.get(param);
147
- // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
148
- if (tsNode === undefined)
149
- continue;
150
- const type = typeChecker.getTypeAtLocation(tsNode);
151
- const objectProps = getObjectTypeProperties(type);
152
- const mut_destructuredProps = new Set();
153
- for (const prop of param.properties) {
154
- if (prop.type === AST_NODE_TYPES.Property &&
155
- prop.key.type === AST_NODE_TYPES.Identifier) {
156
- mut_destructuredProps.add(prop.key.name);
157
- }
158
- }
159
- const missingProps = objectProps.filter((prop) => !mut_destructuredProps.has(prop));
160
- if (missingProps.length > 0) {
161
- context.report({
162
- node: param,
163
- messageId: 'incompleteDestructuring',
164
- data: {
165
- missingProps: missingProps.join(', '),
166
- },
167
- });
168
- }
140
+ checkObjectPatternCompleteness(param, param);
169
141
  }
170
142
  }
171
143
  },
@@ -195,6 +167,43 @@ const getObjectTypeProperties = (type) => {
195
167
  return [];
196
168
  }
197
169
  };
170
+ const collectDestructuredPropNames = (properties) => {
171
+ const mut_names = new Set();
172
+ let mut_hasDynamicComputedKey = false;
173
+ for (const prop of properties) {
174
+ if (prop.type !== AST_NODE_TYPES.Property)
175
+ continue;
176
+ if (!prop.computed) {
177
+ switch (prop.key.type) {
178
+ case AST_NODE_TYPES.Identifier: {
179
+ mut_names.add(prop.key.name);
180
+ break;
181
+ }
182
+ case AST_NODE_TYPES.Literal: {
183
+ if (typeof prop.key.value === 'string') {
184
+ mut_names.add(prop.key.value);
185
+ }
186
+ else if (typeof prop.key.value === 'number') {
187
+ mut_names.add(String(prop.key.value));
188
+ }
189
+ break;
190
+ }
191
+ }
192
+ }
193
+ else if (prop.key.type === AST_NODE_TYPES.Literal &&
194
+ (typeof prop.key.value === 'string' || typeof prop.key.value === 'number')) {
195
+ // Computed key with a static literal value, e.g. { ['data-id']: val }
196
+ mut_names.add(typeof prop.key.value === 'string'
197
+ ? prop.key.value
198
+ : String(prop.key.value));
199
+ }
200
+ else {
201
+ // Dynamic computed key — cannot resolve statically
202
+ mut_hasDynamicComputedKey = true;
203
+ }
204
+ }
205
+ return { names: mut_names, hasDynamicComputedKey: mut_hasDynamicComputedKey };
206
+ };
198
207
  const isReactComponentFunction = (node) => {
199
208
  if (node === undefined || node === null)
200
209
  return false;
@@ -1 +1 @@
1
- {"version":3,"file":"check-destructuring-completeness.mjs","sources":["../../../../src/plugins/ts-restrictions/rules/check-destructuring-completeness.mts"],"sourcesContent":[null],"names":[],"mappings":";;AAgBA,MAAM,yBAAyB,GAAG,mCAAmC;AAE9D,MAAM,8BAA8B,GAGvC;AACF,IAAA,IAAI,EAAE;AACJ,QAAA,IAAI,EAAE,YAAY;AAClB,QAAA,IAAI,EAAE;AACJ,YAAA,WAAW,EACT,iFAAiF;AACpF,SAAA;AACD,QAAA,MAAM,EAAE;AACN,YAAA;AACE,gBAAA,IAAI,EAAE,QAAQ;AACd,gBAAA,UAAU,EAAE;AACV,oBAAA,8BAA8B,EAAE;AAC9B,wBAAA,IAAI,EAAE,SAAS;AACf,wBAAA,WAAW,EACT,4EAA4E;AAC/E,qBAAA;AACD,oBAAA,gBAAgB,EAAE;AAChB,wBAAA,IAAI,EAAE,QAAQ;AACd,wBAAA,WAAW,EACT,4FAA4F;AAC/F,qBAAA;AACF,iBAAA;AACD,gBAAA,oBAAoB,EAAE,KAAK;AAC5B,aAAA;AACF,SAAA;AACD,QAAA,QAAQ,EAAE;AACR,YAAA,uBAAuB,EACrB,gEAAgE;AACnE,SAAA;AACF,KAAA;AAED,IAAA,MAAM,EAAE,CAAC,OAAO,KAAI;AAClB,QAAA,MAAM,cAAc,GAAG,OAAO,CAAC,UAAU,CAAC,cAAc;AAExD,QAAA,IACE,cAAc,EAAE,OAAO,KAAK,SAAS;YACrC,cAAc,CAAC,OAAO,KAAK,IAAI;AAC/B,YAAA,cAAc,CAAC,qBAAqB,KAAK,SAAS,EAClD;AACA,YAAA,OAAO,EAAE;QACX;QAEA,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,EAAE;AAExC,QAAA,MAAM,8BAA8B,GAClC,OAAO,CAAC,8BAA8B,IAAI,IAAI;AAEhD,QAAA,MAAM,gBAAgB,GACpB,OAAO,CAAC,gBAAgB,IAAI,yBAAyB;QAEvD,MAAM,WAAW,GAAG,cAAc,CAAC,OAAO,CAAC,cAAc,EAAE;AAE3D,QAAA,MAAM,qBAAqB,GAAG,cAAc,CAAC,qBAAqB;AAElE,QAAA,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU;AAErC,QAAA,MAAM,mBAAmB,GAAG,CAC1B,IAA+C,KACpC;;AAEX,YAAA,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM;;YAG1B,IAAI,MAAM,EAAE,IAAI,KAAK,cAAc,CAAC,mBAAmB,EAAE;AACvD,gBAAA,OAAO,KAAK;YACd;;YAGA,MAAM,QAAQ,GAAG,UAAU,CAAC,iBAAiB,CAAC,MAAe,CAAC;AAE9D,YAAA,OAAO,QAAQ,CAAC,IAAI,CAAC,CAAC,OAAO,KAC3B,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,gBAAgB,CAAC,CACzC;AACH,QAAA,CAAC;AAED,QAAA,MAAM,kCAAkC,GAAG,CACzC,IAA+C,KACpC;AACX,YAAA,IAAI,CAAC,8BAA8B;AAAE,gBAAA,OAAO,KAAK;AAEjD,YAAA,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM;;YAG1B,IAAI,MAAM,KAAK,SAAS;AAAE,gBAAA,OAAO,KAAK;;;YAItC,IAAI,MAAM,CAAC,IAAI,KAAK,cAAc,CAAC,mBAAmB,EAAE;AACtD,gBAAA,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM;;gBAGjC,IAAI,WAAW,KAAK,SAAS;AAAE,oBAAA,OAAO,KAAK;;gBAG3C,IAAI,WAAW,CAAC,IAAI,KAAK,cAAc,CAAC,cAAc,EAAE;AACtD,oBAAA,MAAM,gBAAgB,GAAG,WAAW,CAAC,MAAM;AAE3C,oBAAA;;AAEE,oBAAA,gBAAgB,EAAE,IAAI,KAAK,cAAc,CAAC,uBAAuB;wBACjE,IAAI,CAAC,IAAI,EAAE,IAAI,KAAK,cAAc,CAAC,UAAU,EAC7C;AACA,wBAAA,MAAM,QAAQ;;AAEZ,wBAAA,IAAI,CAAC,IAAI,CAAC,IAAI,KAAK,cAAc,CAAC;AAChC,8BAAE,IAAI,CAAC,IAAI,CAAC;8BACV,SAAS;wBAEf,IACE,QAAQ,KAAK,SAAS;AACtB,4BAAA,gBAAgB,CAAC,MAAM,CAAC,IAAI,CAC1B,CAAC,KAAK,KACJ,KAAK,CAAC,IAAI,KAAK,cAAc,CAAC,UAAU;AACxC,gCAAA,KAAK,CAAC,IAAI,KAAK,QAAQ,CAC1B,EACD;AACA,4BAAA,OAAO,wBAAwB,CAAC,gBAAgB,CAAC;wBACnD;oBACF;gBACF;gBAEA,IAAI,WAAW,CAAC,IAAI,KAAK,cAAc,CAAC,uBAAuB,EAAE;AAC/D,oBAAA,OAAO,wBAAwB,CAAC,WAAW,CAAC;gBAC9C;YACF;AAEA,YAAA,OAAO,KAAK;AACd,QAAA,CAAC;AAED,QAAA,MAAM,SAAS,GAAG,CAChB,IAA+C,KACvC;YACR,IAAI,IAAI,CAAC,EAAE,CAAC,IAAI,KAAK,cAAc,CAAC,aAAa;gBAAE;;YAGnD,IAAI,IAAI,CAAC,IAAI,KAAK,SAAS,IAAI,IAAI,CAAC,IAAI,KAAK,IAAI;gBAAE;YAEnD,MAAM,WAAW,GACf,mBAAmB,CAAC,IAAI,CAAC,IAAI,kCAAkC,CAAC,IAAI,CAAC;AAEvE,YAAA,IAAI,CAAC,WAAW;gBAAE;;YAGlB,MAAM,cAAc,GAAG,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,IAAI,CAC5C,CAAC,IAAI,KAAK,IAAI,CAAC,IAAI,KAAK,cAAc,CAAC,WAAW,CACnD;AAED,YAAA,IAAI,cAAc;gBAAE;;YAGpB,MAAM,MAAM,GAAG,qBAAqB,CAAC,GAAG,CAAC,IAAI,CAAC,IAAa,CAAC;;YAG5D,IAAI,MAAM,KAAK,SAAS;gBAAE;YAE1B,MAAM,IAAI,GAAG,WAAW,CAAC,iBAAiB,CAAC,MAAM,CAAC;AAElD,YAAA,MAAM,WAAW,GAAG,uBAAuB,CAAC,IAAI,CAAC;AAEjD,YAAA,MAAM,qBAAqB,GAAG,IAAI,GAAG,EAAU;YAE/C,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,EAAE,CAAC,UAAU,EAAE;AACrC,gBAAA,IACE,IAAI,CAAC,IAAI,KAAK,cAAc,CAAC,QAAQ;oBACrC,IAAI,CAAC,GAAG,CAAC,IAAI,KAAK,cAAc,CAAC,UAAU,EAC3C;oBACA,qBAAqB,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC;gBAC1C;YACF;AAEA,YAAA,MAAM,YAAY,GAAG,WAAW,CAAC,MAAM,CACrC,CAAC,IAAI,KAAK,CAAC,qBAAqB,CAAC,GAAG,CAAC,IAAI,CAAC,CAC3C;AAED,YAAA,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE;gBAC3B,OAAO,CAAC,MAAM,CAAC;;oBAEb,IAAI,EAAE,IAAI,CAAC,EAAW;AACtB,oBAAA,SAAS,EAAE,yBAAyB;AACpC,oBAAA,IAAI,EAAE;AACJ,wBAAA,YAAY,EAAE,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC;AACtC,qBAAA;AACF,iBAAA,CAAC;YACJ;AACF,QAAA,CAAC;QAED,OAAO;AACL,YAAA,kBAAkB,EAAE,SAAS;AAC7B,YAAA,uBAAuB,EAAE,CAAC,IAAI,KAAI;AAChC,gBAAA,IAAI,CAAC,8BAA8B;oBAAE;AAErC,gBAAA,IAAI,CAAC,wBAAwB,CAAC,IAAI,CAAC;oBAAE;AAErC,gBAAA,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,MAAM,EAAE;oBAC/B,IAAI,KAAK,CAAC,IAAI,KAAK,cAAc,CAAC,aAAa,EAAE;;wBAE/C,MAAM,cAAc,GAAG,KAAK,CAAC,UAAU,CAAC,IAAI,CAC1C,CAAC,IAAI,KAAK,IAAI,CAAC,IAAI,KAAK,cAAc,CAAC,WAAW,CACnD;AAED,wBAAA,IAAI,cAAc;4BAAE;;wBAGpB,MAAM,MAAM,GAAG,qBAAqB,CAAC,GAAG,CAAC,KAAc,CAAC;;wBAGxD,IAAI,MAAM,KAAK,SAAS;4BAAE;wBAE1B,MAAM,IAAI,GAAG,WAAW,CAAC,iBAAiB,CAAC,MAAM,CAAC;AAElD,wBAAA,MAAM,WAAW,GAAG,uBAAuB,CAAC,IAAI,CAAC;AAEjD,wBAAA,MAAM,qBAAqB,GAAG,IAAI,GAAG,EAAU;AAE/C,wBAAA,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,UAAU,EAAE;AACnC,4BAAA,IACE,IAAI,CAAC,IAAI,KAAK,cAAc,CAAC,QAAQ;gCACrC,IAAI,CAAC,GAAG,CAAC,IAAI,KAAK,cAAc,CAAC,UAAU,EAC3C;gCACA,qBAAqB,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC;4BAC1C;wBACF;AAEA,wBAAA,MAAM,YAAY,GAAG,WAAW,CAAC,MAAM,CACrC,CAAC,IAAI,KAAK,CAAC,qBAAqB,CAAC,GAAG,CAAC,IAAI,CAAC,CAC3C;AAED,wBAAA,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE;4BAC3B,OAAO,CAAC,MAAM,CAAC;AACb,gCAAA,IAAI,EAAE,KAAK;AACX,gCAAA,SAAS,EAAE,yBAAyB;AACpC,gCAAA,IAAI,EAAE;AACJ,oCAAA,YAAY,EAAE,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC;AACtC,iCAAA;AACF,6BAAA,CAAC;wBACJ;oBACF;gBACF;YACF,CAAC;SACF;IACH,CAAC;AACD,IAAA,cAAc,EAAE,CAAC,EAAE,8BAA8B,EAAE,IAAI,EAAE,CAAC;;AAG5D;AACA,MAAM,uBAAuB,GAAG,CAAC,IAAa,KAAuB;AACnE,IAAA,IAAI;AACF,QAAA,MAAM,UAAU,GAAG,IAAI,CAAC,aAAa,EAAE;;AAGvC,QAAA,IAAI,UAAU,CAAC,MAAM,GAAG,IAAI,EAAE;AAC5B,YAAA,OAAO,EAAE;QACX;AAEA,QAAA,OAAO;aACJ,GAAG,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,IAAI;AACvB,aAAA,MAAM,CACL,CAAC,IAAI;;AAEH,QAAA,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;;YAEtB,OAAO,IAAI,KAAK,QAAQ;AACxB,YAAA,IAAI,CAAC,MAAM,GAAG,CAAC,CAClB;IACL;AAAE,IAAA,MAAM;;AAEN,QAAA,OAAO,EAAE;IACX;AACF,CAAC;AAED,MAAM,wBAAwB,GAAG,CAC/B,IAAoD,KACzC;AACX,IAAA,IAAI,IAAI,KAAK,SAAS,IAAI,IAAI,KAAK,IAAI;AAAE,QAAA,OAAO,KAAK;;IAGrD,IAAI,IAAI,CAAC,IAAI,KAAK,cAAc,CAAC,uBAAuB,EAAE;AACxD,QAAA,MAAM,EAAE,IAAI,EAAE,GAAG,IAAI;QAErB,IAAI,IAAI,CAAC,IAAI,KAAK,cAAc,CAAC,cAAc,EAAE;YAC/C,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,SAAS,KAAI;AAClC,gBAAA,IAAI,SAAS,CAAC,IAAI,KAAK,cAAc,CAAC,eAAe;AAAE,oBAAA,OAAO,KAAK;AAEnE,gBAAA,MAAM,EAAE,QAAQ,EAAE,GAAG,SAAS;;AAG9B,gBAAA,IAAI,QAAQ,KAAK,IAAI,IAAI,QAAQ,KAAK,SAAS;AAAE,oBAAA,OAAO,KAAK;AAE7D,gBAAA,MAAM,OAAO,GAAI,QAAwC,CAAC,IAAI;AAE9D,gBAAA,OAAO,OAAO,KAAK,YAAY,IAAI,OAAO,KAAK,aAAa;AAC9D,YAAA,CAAC,CAAC;QACJ;AAEA,QAAA,MAAM,QAAQ,GAAI,IAAoC,CAAC,IAAI;AAE3D,QAAA,OAAO,QAAQ,KAAK,YAAY,IAAI,QAAQ,KAAK,aAAa;IAChE;AAEA,IAAA,OAAO,KAAK;AACd,CAAC;;;;"}
1
+ {"version":3,"file":"check-destructuring-completeness.mjs","sources":["../../../../src/plugins/ts-restrictions/rules/check-destructuring-completeness.mts"],"sourcesContent":[null],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eslint-config-typed",
3
- "version": "4.9.1",
3
+ "version": "4.9.2",
4
4
  "private": false,
5
5
  "keywords": [
6
6
  "typescript"
@@ -148,28 +148,18 @@ export const checkDestructuringCompleteness: TSESLint.RuleModule<
148
148
  return false;
149
149
  };
150
150
 
151
- const checkNode = (
152
- node: DeepReadonly<TSESTree.VariableDeclarator>,
151
+ const checkObjectPatternCompleteness = (
152
+ objectPattern: DeepReadonly<TSESTree.ObjectPattern>,
153
+ tsSourceNode: DeepReadonly<TSESTree.Node>,
153
154
  ): void => {
154
- if (node.id.type !== AST_NODE_TYPES.ObjectPattern) return;
155
-
156
- // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
157
- if (node.init === undefined || node.init === null) return;
158
-
159
- const shouldCheck =
160
- hasDirectiveComment(node) || isReactComponentPropsDestructuring(node);
161
-
162
- if (!shouldCheck) return;
163
-
164
- // If rest element is used, skip completeness check
165
- const hasRestElement = node.id.properties.some(
155
+ const hasRestElement = objectPattern.properties.some(
166
156
  (prop) => prop.type === AST_NODE_TYPES.RestElement,
167
157
  );
168
158
 
169
159
  if (hasRestElement) return;
170
160
 
171
161
  // eslint-disable-next-line total-functions/no-unsafe-type-assertion
172
- const tsNode = esTreeNodeToTSNodeMap.get(node.init as never);
162
+ const tsNode = esTreeNodeToTSNodeMap.get(tsSourceNode as never);
173
163
 
174
164
  // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
175
165
  if (tsNode === undefined) return;
@@ -178,25 +168,20 @@ export const checkDestructuringCompleteness: TSESLint.RuleModule<
178
168
 
179
169
  const objectProps = getObjectTypeProperties(type);
180
170
 
181
- const mut_destructuredProps = new Set<string>();
171
+ const collected = collectDestructuredPropNames(objectPattern.properties);
182
172
 
183
- for (const prop of node.id.properties) {
184
- if (
185
- prop.type === AST_NODE_TYPES.Property &&
186
- prop.key.type === AST_NODE_TYPES.Identifier
187
- ) {
188
- mut_destructuredProps.add(prop.key.name);
189
- }
190
- }
173
+ // Dynamic computed properties cannot be resolved statically,
174
+ // so skip completeness check when they are present.
175
+ if (collected.hasDynamicComputedKey) return;
191
176
 
192
177
  const missingProps = objectProps.filter(
193
- (prop) => !mut_destructuredProps.has(prop),
178
+ (prop) => !collected.names.has(prop),
194
179
  );
195
180
 
196
181
  if (missingProps.length > 0) {
197
182
  context.report({
198
183
  // eslint-disable-next-line total-functions/no-unsafe-type-assertion
199
- node: node.id as never,
184
+ node: objectPattern as never,
200
185
  messageId: 'incompleteDestructuring',
201
186
  data: {
202
187
  missingProps: missingProps.join(', '),
@@ -206,7 +191,19 @@ export const checkDestructuringCompleteness: TSESLint.RuleModule<
206
191
  };
207
192
 
208
193
  return {
209
- VariableDeclarator: checkNode,
194
+ VariableDeclarator: (node) => {
195
+ if (node.id.type !== AST_NODE_TYPES.ObjectPattern) return;
196
+
197
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
198
+ if (node.init === undefined || node.init === null) return;
199
+
200
+ const shouldCheck =
201
+ hasDirectiveComment(node) || isReactComponentPropsDestructuring(node);
202
+
203
+ if (!shouldCheck) return;
204
+
205
+ checkObjectPatternCompleteness(node.id, node.init);
206
+ },
210
207
  ArrowFunctionExpression: (node) => {
211
208
  if (!alwaysCheckReactComponentProps) return;
212
209
 
@@ -214,47 +211,7 @@ export const checkDestructuringCompleteness: TSESLint.RuleModule<
214
211
 
215
212
  for (const param of node.params) {
216
213
  if (param.type === AST_NODE_TYPES.ObjectPattern) {
217
- // If rest element is used, skip completeness check
218
- const hasRestElement = param.properties.some(
219
- (prop) => prop.type === AST_NODE_TYPES.RestElement,
220
- );
221
-
222
- if (hasRestElement) continue;
223
-
224
- // eslint-disable-next-line total-functions/no-unsafe-type-assertion
225
- const tsNode = esTreeNodeToTSNodeMap.get(param as never);
226
-
227
- // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
228
- if (tsNode === undefined) continue;
229
-
230
- const type = typeChecker.getTypeAtLocation(tsNode);
231
-
232
- const objectProps = getObjectTypeProperties(type);
233
-
234
- const mut_destructuredProps = new Set<string>();
235
-
236
- for (const prop of param.properties) {
237
- if (
238
- prop.type === AST_NODE_TYPES.Property &&
239
- prop.key.type === AST_NODE_TYPES.Identifier
240
- ) {
241
- mut_destructuredProps.add(prop.key.name);
242
- }
243
- }
244
-
245
- const missingProps = objectProps.filter(
246
- (prop) => !mut_destructuredProps.has(prop),
247
- );
248
-
249
- if (missingProps.length > 0) {
250
- context.report({
251
- node: param,
252
- messageId: 'incompleteDestructuring',
253
- data: {
254
- missingProps: missingProps.join(', '),
255
- },
256
- });
257
- }
214
+ checkObjectPatternCompleteness(param, param);
258
215
  }
259
216
  }
260
217
  },
@@ -289,6 +246,56 @@ const getObjectTypeProperties = (type: ts.Type): readonly string[] => {
289
246
  }
290
247
  };
291
248
 
249
+ const collectDestructuredPropNames = (
250
+ properties: DeepReadonly<TSESTree.ObjectPattern['properties']>,
251
+ ): Readonly<{
252
+ names: ReadonlySet<string>;
253
+ hasDynamicComputedKey: boolean;
254
+ }> => {
255
+ const mut_names = new Set<string>();
256
+
257
+ let mut_hasDynamicComputedKey = false;
258
+
259
+ for (const prop of properties) {
260
+ if (prop.type !== AST_NODE_TYPES.Property) continue;
261
+
262
+ if (!prop.computed) {
263
+ switch (prop.key.type) {
264
+ case AST_NODE_TYPES.Identifier: {
265
+ mut_names.add(prop.key.name);
266
+
267
+ break;
268
+ }
269
+
270
+ case AST_NODE_TYPES.Literal: {
271
+ if (typeof prop.key.value === 'string') {
272
+ mut_names.add(prop.key.value);
273
+ } else if (typeof prop.key.value === 'number') {
274
+ mut_names.add(String(prop.key.value));
275
+ }
276
+
277
+ break;
278
+ }
279
+ }
280
+ } else if (
281
+ prop.key.type === AST_NODE_TYPES.Literal &&
282
+ (typeof prop.key.value === 'string' || typeof prop.key.value === 'number')
283
+ ) {
284
+ // Computed key with a static literal value, e.g. { ['data-id']: val }
285
+ mut_names.add(
286
+ typeof prop.key.value === 'string'
287
+ ? prop.key.value
288
+ : String(prop.key.value),
289
+ );
290
+ } else {
291
+ // Dynamic computed key — cannot resolve statically
292
+ mut_hasDynamicComputedKey = true;
293
+ }
294
+ }
295
+
296
+ return { names: mut_names, hasDynamicComputedKey: mut_hasDynamicComputedKey };
297
+ };
298
+
292
299
  const isReactComponentFunction = (
293
300
  node: DeepReadonly<TSESTree.Node> | undefined | null,
294
301
  ): boolean => {
@@ -125,6 +125,64 @@ describe('check-destructuring-completeness', () => {
125
125
  };
126
126
  `,
127
127
  },
128
+ {
129
+ name: 'handles string literal keys with directive - complete',
130
+ code: dedent`
131
+ const obj: { a: number; 'data-e2eId': string } = { a: 1, 'data-e2eId': 'test' };
132
+ // @check-destructuring-completeness
133
+ const { a, 'data-e2eId': e2eId } = obj;
134
+ `,
135
+ },
136
+ {
137
+ name: 'handles string literal keys in React component props - parameter destructuring',
138
+ code: dedent`
139
+ type Props = { a: number; b: string; 'data-e2eId': string };
140
+ const MyComponent = ({ a, b, 'data-e2eId': e2eId }: Props) => <div>{a}{b}{e2eId}</div>;
141
+ `,
142
+ },
143
+ {
144
+ name: 'handles string literal keys in React component props - internal destructuring',
145
+ code: dedent`
146
+ type Props = { a: number; b: string; 'data-e2eId': string };
147
+ const MyComponent = (props: Props) => {
148
+ const { a, b, 'data-e2eId': e2eId } = props;
149
+ return <div>{a}{b}{e2eId}</div>;
150
+ };
151
+ `,
152
+ },
153
+ {
154
+ name: 'handles number literal keys with directive - complete',
155
+ code: dedent`
156
+ const obj: { 0: string; 1: number } = { 0: 'a', 1: 2 };
157
+ // @check-destructuring-completeness
158
+ const { 0: first, 1: second } = obj;
159
+ `,
160
+ },
161
+ {
162
+ name: 'skips check when dynamic computed key is present with directive',
163
+ code: dedent`
164
+ const key = 'a' as string;
165
+ const obj: { a: number; b: string } = { a: 1, b: 'hello' };
166
+ // @check-destructuring-completeness
167
+ const { [key]: val } = obj;
168
+ `,
169
+ },
170
+ {
171
+ name: 'skips check when dynamic computed key is present in React component props',
172
+ code: dedent`
173
+ const key = 'a' as string;
174
+ type Props = { a: number; b: string };
175
+ const MyComponent = ({ [key]: val }: Props) => <div>{val}</div>;
176
+ `,
177
+ },
178
+ {
179
+ name: 'handles computed key with static string literal',
180
+ code: dedent`
181
+ const obj: { a: number; 'data-id': string } = { a: 1, 'data-id': 'test' };
182
+ // @check-destructuring-completeness
183
+ const { a, ['data-id']: dataId } = obj;
184
+ `,
185
+ },
128
186
  {
129
187
  name: 'does not check React component props when disabled - parameter',
130
188
  code: dedent`
@@ -165,6 +223,43 @@ describe('check-destructuring-completeness', () => {
165
223
  options: [{ directiveKeyword: '@custom-check' }],
166
224
  errors: [{ messageId: 'incompleteDestructuring' }],
167
225
  },
226
+ {
227
+ name: 'reports missing string literal key with directive',
228
+ code: dedent`
229
+ const obj: { a: number; 'data-e2eId': string } = { a: 1, 'data-e2eId': 'test' };
230
+ // @check-destructuring-completeness
231
+ const { a } = obj;
232
+ `,
233
+ errors: [{ messageId: 'incompleteDestructuring' }],
234
+ },
235
+ {
236
+ name: 'reports missing string literal key in React component props - parameter',
237
+ code: dedent`
238
+ type Props = { a: number; 'data-e2eId': string };
239
+ const MyComponent = ({ a }: Props) => <div>{a}</div>;
240
+ `,
241
+ errors: [{ messageId: 'incompleteDestructuring' }],
242
+ },
243
+ {
244
+ name: 'reports missing string literal key in React component props - internal',
245
+ code: dedent`
246
+ type Props = { a: number; 'data-e2eId': string };
247
+ const MyComponent = (props: Props) => {
248
+ const { a } = props;
249
+ return <div>{a}</div>;
250
+ };
251
+ `,
252
+ errors: [{ messageId: 'incompleteDestructuring' }],
253
+ },
254
+ {
255
+ name: 'reports missing number literal key with directive',
256
+ code: dedent`
257
+ const obj: { 0: string; 1: number } = { 0: 'a', 1: 2 };
258
+ // @check-destructuring-completeness
259
+ const { 0: first } = obj;
260
+ `,
261
+ errors: [{ messageId: 'incompleteDestructuring' }],
262
+ },
168
263
  {
169
264
  name: 'checks React component props - parameter destructuring incomplete',
170
265
  code: dedent`