@typescript-eslint/typescript-estree 8.52.1-alpha.0 → 8.52.1-alpha.10

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,2 +1,3 @@
1
1
  import * as ts from 'typescript';
2
- export declare function checkSyntaxError(tsNode: ts.Node): void;
2
+ import type { TSNode } from './ts-estree';
3
+ export declare function checkSyntaxError(tsNode: ts.Node, parent: TSNode, allowPattern: boolean): void;
@@ -38,7 +38,7 @@ const ts = __importStar(require("typescript"));
38
38
  const check_modifiers_1 = require("./check-modifiers");
39
39
  const node_utils_1 = require("./node-utils");
40
40
  const SyntaxKind = ts.SyntaxKind;
41
- function checkSyntaxError(tsNode) {
41
+ function checkSyntaxError(tsNode, parent, allowPattern) {
42
42
  (0, check_modifiers_1.checkModifiers)(tsNode);
43
43
  const node = tsNode;
44
44
  switch (node.kind) {
@@ -90,19 +90,12 @@ function checkSyntaxError(tsNode) {
90
90
  if (node.parent.kind === SyntaxKind.VariableDeclarationList) {
91
91
  const variableDeclarationList = node.parent;
92
92
  const kind = (0, node_utils_1.getDeclarationKind)(variableDeclarationList);
93
- if ((variableDeclarationList.parent.kind === SyntaxKind.ForInStatement ||
94
- variableDeclarationList.parent.kind === SyntaxKind.ForStatement) &&
95
- (kind === 'using' || kind === 'await using')) {
96
- if (!node.initializer) {
97
- throw (0, node_utils_1.createError)(node, `'${kind}' declarations may not be initialized in for statement.`);
93
+ if (kind === 'using' || kind === 'await using') {
94
+ if (variableDeclarationList.parent.kind === SyntaxKind.ForInStatement) {
95
+ throw (0, node_utils_1.createError)(variableDeclarationList, `The left-hand side of a 'for...in' statement cannot be a '${kind}' declaration.`);
98
96
  }
99
- if (node.name.kind !== SyntaxKind.Identifier) {
100
- throw (0, node_utils_1.createError)(node.name, `'${kind}' declarations may not have binding patterns.`);
101
- }
102
- }
103
- if (variableDeclarationList.parent.kind === SyntaxKind.VariableStatement) {
104
- const variableStatement = variableDeclarationList.parent;
105
- if (kind === 'using' || kind === 'await using') {
97
+ if (variableDeclarationList.parent.kind === SyntaxKind.ForStatement ||
98
+ variableDeclarationList.parent.kind === SyntaxKind.VariableStatement) {
106
99
  if (!node.initializer) {
107
100
  throw (0, node_utils_1.createError)(node, `'${kind}' declarations must be initialized.`);
108
101
  }
@@ -110,6 +103,9 @@ function checkSyntaxError(tsNode) {
110
103
  throw (0, node_utils_1.createError)(node.name, `'${kind}' declarations may not have binding patterns.`);
111
104
  }
112
105
  }
106
+ }
107
+ if (variableDeclarationList.parent.kind === SyntaxKind.VariableStatement) {
108
+ const variableStatement = variableDeclarationList.parent;
113
109
  const hasDeclareKeyword = (0, node_utils_1.hasModifier)(SyntaxKind.DeclareKeyword, variableStatement);
114
110
  // Definite assignment only allowed for non-declare let and var
115
111
  if ((hasDeclareKeyword ||
@@ -181,13 +177,6 @@ function checkSyntaxError(tsNode) {
181
177
  throw (0, node_utils_1.createError)(node, 'Tagged template expressions are not permitted in an optional chain.');
182
178
  }
183
179
  break;
184
- case SyntaxKind.ClassDeclaration:
185
- if (!node.name &&
186
- (!(0, node_utils_1.hasModifier)(ts.SyntaxKind.ExportKeyword, node) ||
187
- !(0, node_utils_1.hasModifier)(ts.SyntaxKind.DefaultKeyword, node))) {
188
- throw (0, node_utils_1.createError)(node, "A class declaration without the 'default' modifier must have a name.");
189
- }
190
- break;
191
180
  case SyntaxKind.BinaryExpression:
192
181
  if (node.operatorToken.kind !== SyntaxKind.InKeyword &&
193
182
  node.left.kind === SyntaxKind.PrivateIdentifier) {
@@ -246,12 +235,32 @@ function checkSyntaxError(tsNode) {
246
235
  }
247
236
  break;
248
237
  }
249
- case SyntaxKind.ImportDeclaration:
238
+ case SyntaxKind.ImportDeclaration: {
239
+ const { importClause } = node;
240
+ if (
241
+ // TODO swap to `phaseModifier` once we add support for `import defer`
242
+ // https://github.com/estree/estree/issues/328
243
+ // eslint-disable-next-line @typescript-eslint/no-deprecated
244
+ importClause?.isTypeOnly &&
245
+ importClause.name &&
246
+ importClause.namedBindings) {
247
+ throw (0, node_utils_1.createError)(importClause, 'A type-only import can specify a default import or named bindings, but not both.');
248
+ }
250
249
  assertModuleSpecifier(node, false);
251
250
  break;
251
+ }
252
252
  case SyntaxKind.ExportDeclaration:
253
253
  assertModuleSpecifier(node, node.exportClause?.kind === SyntaxKind.NamedExports);
254
254
  break;
255
+ case SyntaxKind.ExportSpecifier: {
256
+ const local = node.propertyName ?? node.name;
257
+ if (local.kind === SyntaxKind.StringLiteral &&
258
+ parent.kind === SyntaxKind.ExportDeclaration &&
259
+ parent.moduleSpecifier?.kind !== SyntaxKind.StringLiteral) {
260
+ throw (0, node_utils_1.createError)(local, 'A string literal cannot be used as a local exported binding without `from`.');
261
+ }
262
+ break;
263
+ }
255
264
  case SyntaxKind.CallExpression:
256
265
  if (node.expression.kind === SyntaxKind.ImportKeyword &&
257
266
  node.arguments.length !== 1 &&
@@ -259,6 +268,138 @@ function checkSyntaxError(tsNode) {
259
268
  throw (0, node_utils_1.createError)(node.arguments.length > 1 ? node.arguments[2] : node, 'Dynamic import requires exactly one or two arguments.');
260
269
  }
261
270
  break;
271
+ case SyntaxKind.ClassDeclaration:
272
+ if (!node.name &&
273
+ (!(0, node_utils_1.hasModifier)(ts.SyntaxKind.ExportKeyword, node) ||
274
+ !(0, node_utils_1.hasModifier)(ts.SyntaxKind.DefaultKeyword, node))) {
275
+ throw (0, node_utils_1.createError)(node, "A class declaration without the 'default' modifier must have a name.");
276
+ }
277
+ // intentional fallthrough
278
+ case SyntaxKind.ClassExpression: {
279
+ const heritageClauses = node.heritageClauses ?? [];
280
+ let seenExtendsClause = false;
281
+ let seenImplementsClause = false;
282
+ for (const heritageClause of heritageClauses) {
283
+ const { token, types } = heritageClause;
284
+ if (types.length === 0) {
285
+ throw (0, node_utils_1.createError)(heritageClause, `'${ts.tokenToString(token)}' list cannot be empty.`);
286
+ }
287
+ if (token === SyntaxKind.ExtendsKeyword) {
288
+ if (seenExtendsClause) {
289
+ throw (0, node_utils_1.createError)(heritageClause, "'extends' clause already seen.");
290
+ }
291
+ if (seenImplementsClause) {
292
+ throw (0, node_utils_1.createError)(heritageClause, "'extends' clause must precede 'implements' clause.");
293
+ }
294
+ if (types.length > 1) {
295
+ throw (0, node_utils_1.createError)(types[1], 'Classes can only extend a single class.');
296
+ }
297
+ seenExtendsClause = true;
298
+ }
299
+ else {
300
+ // `implements`
301
+ if (seenImplementsClause) {
302
+ throw (0, node_utils_1.createError)(heritageClause, "'implements' clause already seen.");
303
+ }
304
+ for (const heritageType of heritageClause.types) {
305
+ if (!(0, node_utils_1.isEntityNameExpression)(heritageType.expression) ||
306
+ ts.isOptionalChain(heritageType.expression)) {
307
+ throw (0, node_utils_1.createError)(heritageType, 'A class can only implement an identifier/qualified-name with optional type arguments.');
308
+ }
309
+ }
310
+ seenImplementsClause = true;
311
+ }
312
+ }
313
+ break;
314
+ }
315
+ case SyntaxKind.InterfaceDeclaration: {
316
+ const interfaceHeritageClauses = node.heritageClauses ?? [];
317
+ let seenExtendsClause = false;
318
+ for (const heritageClause of interfaceHeritageClauses) {
319
+ const { token, types } = heritageClause;
320
+ if (token === SyntaxKind.ImplementsKeyword) {
321
+ throw (0, node_utils_1.createError)(heritageClause, "Interface declaration cannot have 'implements' clause.");
322
+ }
323
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
324
+ if (token !== SyntaxKind.ExtendsKeyword) {
325
+ throw (0, node_utils_1.createError)(heritageClause, 'Unexpected token.');
326
+ }
327
+ if (types.length === 0) {
328
+ throw (0, node_utils_1.createError)(heritageClause, `'${ts.tokenToString(token)}' list cannot be empty.`);
329
+ }
330
+ if (seenExtendsClause) {
331
+ throw (0, node_utils_1.createError)(heritageClause, "'extends' clause already seen.");
332
+ }
333
+ seenExtendsClause = true;
334
+ for (const heritageType of heritageClause.types) {
335
+ if (!(0, node_utils_1.isEntityNameExpression)(heritageType.expression) ||
336
+ ts.isOptionalChain(heritageType.expression)) {
337
+ throw (0, node_utils_1.createError)(heritageType, 'Interface declaration can only extend an identifier/qualified name with optional type arguments.');
338
+ }
339
+ }
340
+ }
341
+ break;
342
+ }
343
+ case SyntaxKind.GetAccessor:
344
+ case SyntaxKind.SetAccessor:
345
+ if (node.parent.kind === SyntaxKind.InterfaceDeclaration ||
346
+ node.parent.kind === SyntaxKind.TypeLiteral) {
347
+ return;
348
+ }
349
+ // otherwise, it is a non-type accessor - intentional fallthrough
350
+ case SyntaxKind.MethodDeclaration: {
351
+ const isAbstract = (0, node_utils_1.hasModifier)(SyntaxKind.AbstractKeyword, node);
352
+ if (isAbstract && node.body) {
353
+ throw (0, node_utils_1.createError)(node.name, node.kind === SyntaxKind.GetAccessor ||
354
+ node.kind === SyntaxKind.SetAccessor
355
+ ? 'An abstract accessor cannot have an implementation.'
356
+ : `Method '${(0, node_utils_1.declarationNameToString)(node.name)}' cannot have an implementation because it is marked abstract.`);
357
+ }
358
+ break;
359
+ }
360
+ case SyntaxKind.ObjectLiteralExpression: {
361
+ if (!allowPattern) {
362
+ for (const property of node.properties) {
363
+ if ((property.kind === SyntaxKind.GetAccessor ||
364
+ property.kind === SyntaxKind.SetAccessor ||
365
+ property.kind === SyntaxKind.MethodDeclaration) &&
366
+ !property.body) {
367
+ throw (0, node_utils_1.createError)(property.end - 1, "'{' expected.", node.getSourceFile());
368
+ }
369
+ }
370
+ }
371
+ break;
372
+ }
373
+ case SyntaxKind.ImportEqualsDeclaration:
374
+ if (node.isTypeOnly &&
375
+ node.moduleReference.kind !== SyntaxKind.ExternalModuleReference) {
376
+ throw (0, node_utils_1.createError)(node, "An import alias cannot use 'import type'");
377
+ }
378
+ break;
379
+ case SyntaxKind.ModuleDeclaration: {
380
+ if (node.flags & ts.NodeFlags.GlobalAugmentation) {
381
+ const { body } = node;
382
+ if (body == null || body.kind === SyntaxKind.ModuleDeclaration) {
383
+ throw (0, node_utils_1.createError)(node.body ?? node, 'Expected a valid module body');
384
+ }
385
+ const { name } = node;
386
+ if (name.kind !== ts.SyntaxKind.Identifier) {
387
+ throw (0, node_utils_1.createError)(name, 'global module augmentation must have an Identifier id');
388
+ }
389
+ return;
390
+ }
391
+ if (ts.isStringLiteral(node.name)) {
392
+ return;
393
+ }
394
+ if (node.body == null) {
395
+ throw (0, node_utils_1.createError)(node, 'Expected a module body');
396
+ }
397
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- Fixme: confirm if it's possible
398
+ if (node.name.kind !== ts.SyntaxKind.Identifier) {
399
+ throw (0, node_utils_1.createError)(node.name, '`namespace`s must have an Identifier id');
400
+ }
401
+ break;
402
+ }
262
403
  case SyntaxKind.ForInStatement:
263
404
  case SyntaxKind.ForOfStatement: {
264
405
  checkForStatementDeclaration(node);
@@ -281,10 +422,6 @@ function checkForStatementDeclaration(node) {
281
422
  else if (declaration.type) {
282
423
  throw (0, node_utils_1.createError)(declaration, `The variable declaration of a '${loop}' statement cannot have a type annotation.`);
283
424
  }
284
- if (kind === SyntaxKind.ForInStatement &&
285
- initializer.flags & ts.NodeFlags.Using) {
286
- throw (0, node_utils_1.createError)(initializer, "The left-hand side of a 'for...in' statement cannot be a 'using' declaration.");
287
- }
288
425
  }
289
426
  else if (!(0, node_utils_1.isValidAssignmentTarget)(initializer) &&
290
427
  initializer.kind !== SyntaxKind.ObjectLiteralExpression &&
package/dist/convert.d.ts CHANGED
@@ -83,7 +83,7 @@ export declare class Converter {
83
83
  * @param typeParameters ts.Node typeParameters
84
84
  * @returns TypeParameterDeclaration node
85
85
  */
86
- private convertTSTypeParametersToTypeParametersDeclaration;
86
+ private convertTypeParameters;
87
87
  /**
88
88
  * Converts an array of ts.Node parameters into an array of ESTreeNode params
89
89
  * @param parameters An array of ts.Node params to be converted
package/dist/convert.js CHANGED
@@ -51,15 +51,6 @@ const SyntaxKind = ts.SyntaxKind;
51
51
  function convertError(error) {
52
52
  return (0, node_utils_1.createError)(error.start, ('message' in error && error.message) || error.messageText, error.file);
53
53
  }
54
- function isPropertyAccessEntityNameExpression(node) {
55
- return (ts.isPropertyAccessExpression(node) &&
56
- ts.isIdentifier(node.name) &&
57
- isEntityNameExpression(node.expression));
58
- }
59
- function isEntityNameExpression(node) {
60
- return (node.kind === SyntaxKind.Identifier ||
61
- isPropertyAccessEntityNameExpression(node));
62
- }
63
54
  class Converter {
64
55
  allowPattern = false;
65
56
  ast;
@@ -76,11 +67,11 @@ class Converter {
76
67
  this.ast = ast;
77
68
  this.options = { ...options };
78
69
  }
79
- #checkSyntaxError(node) {
70
+ #checkSyntaxError(node, parent) {
80
71
  if (this.options.allowInvalidAST) {
81
72
  return;
82
73
  }
83
- (0, check_syntax_errors_1.checkSyntaxError)(node);
74
+ (0, check_syntax_errors_1.checkSyntaxError)(node, parent, this.allowPattern);
84
75
  }
85
76
  #throwError(node, message) {
86
77
  if (this.options.allowInvalidAST) {
@@ -289,7 +280,11 @@ class Converter {
289
280
  * @param typeParameters ts.Node typeParameters
290
281
  * @returns TypeParameterDeclaration node
291
282
  */
292
- convertTSTypeParametersToTypeParametersDeclaration(typeParameters) {
283
+ convertTypeParameters(node) {
284
+ const { typeParameters } = node;
285
+ if (!typeParameters) {
286
+ return undefined;
287
+ }
293
288
  const greaterThanToken = (0, node_utils_1.findNextToken)(typeParameters, this.ast, this.ast);
294
289
  const range = [
295
290
  typeParameters.pos - 1,
@@ -334,12 +329,13 @@ class Converter {
334
329
  if (!node) {
335
330
  return null;
336
331
  }
337
- this.#checkSyntaxError(node);
338
332
  const pattern = this.allowPattern;
339
333
  if (allowPattern != null) {
340
334
  this.allowPattern = allowPattern;
341
335
  }
342
- const result = this.convertNode(node, (parent ?? node.parent));
336
+ const parentNode = (parent ?? node.parent);
337
+ this.#checkSyntaxError(node, parentNode);
338
+ const result = this.convertNode(node, parentNode);
343
339
  this.registerTSNodeInNodeMap(node, result);
344
340
  this.allowPattern = pattern;
345
341
  return result;
@@ -449,8 +445,7 @@ class Converter {
449
445
  readonly: (0, node_utils_1.hasModifier)(SyntaxKind.ReadonlyKeyword, node),
450
446
  returnType: node.type && this.convertTypeAnnotation(node.type, node),
451
447
  static: (0, node_utils_1.hasModifier)(SyntaxKind.StaticKeyword, node),
452
- typeParameters: node.typeParameters &&
453
- this.convertTSTypeParametersToTypeParametersDeclaration(node.typeParameters),
448
+ typeParameters: this.convertTypeParameters(node),
454
449
  });
455
450
  }
456
451
  /**
@@ -647,8 +642,7 @@ class Converter {
647
642
  id: this.convertChild(node.name),
648
643
  params: this.convertParameters(node.parameters),
649
644
  returnType: node.type && this.convertTypeAnnotation(node.type, node),
650
- typeParameters: node.typeParameters &&
651
- this.convertTSTypeParametersToTypeParametersDeclaration(node.typeParameters),
645
+ typeParameters: this.convertTypeParameters(node),
652
646
  });
653
647
  return this.fixExports(node, result);
654
648
  }
@@ -727,19 +721,9 @@ class Converter {
727
721
  typeAnnotation: undefined,
728
722
  });
729
723
  }
730
- const properties = [];
731
- for (const property of node.properties) {
732
- if ((property.kind === SyntaxKind.GetAccessor ||
733
- property.kind === SyntaxKind.SetAccessor ||
734
- property.kind === SyntaxKind.MethodDeclaration) &&
735
- !property.body) {
736
- this.#throwError(property.end - 1, "'{' expected.");
737
- }
738
- properties.push(this.convertChild(property));
739
- }
740
724
  return this.createNode(node, {
741
725
  type: ts_estree_1.AST_NODE_TYPES.ObjectExpression,
742
- properties,
726
+ properties: this.convertChildren(node.properties),
743
727
  });
744
728
  }
745
729
  case SyntaxKind.PropertyAssignment: {
@@ -832,13 +816,6 @@ class Converter {
832
816
  }
833
817
  // otherwise, it is a non-type accessor - intentional fallthrough
834
818
  case SyntaxKind.MethodDeclaration: {
835
- const isAbstract = (0, node_utils_1.hasModifier)(SyntaxKind.AbstractKeyword, node);
836
- if (isAbstract && node.body) {
837
- this.#throwError(node.name, node.kind === SyntaxKind.GetAccessor ||
838
- node.kind === SyntaxKind.SetAccessor
839
- ? 'An abstract accessor cannot have an implementation.'
840
- : `Method '${(0, node_utils_1.declarationNameToString)(node.name, this.ast)}' cannot have an implementation because it is marked abstract.`);
841
- }
842
819
  const method = this.createNode(node, {
843
820
  type: !node.body
844
821
  ? ts_estree_1.AST_NODE_TYPES.TSEmptyBodyFunctionExpression
@@ -852,8 +829,7 @@ class Converter {
852
829
  id: null,
853
830
  params: [],
854
831
  returnType: node.type && this.convertTypeAnnotation(node.type, node),
855
- typeParameters: node.typeParameters &&
856
- this.convertTSTypeParametersToTypeParametersDeclaration(node.typeParameters),
832
+ typeParameters: this.convertTypeParameters(node),
857
833
  });
858
834
  if (method.typeParameters) {
859
835
  this.fixParentLocation(method, method.typeParameters.range);
@@ -874,6 +850,7 @@ class Converter {
874
850
  }
875
851
  else {
876
852
  // class
853
+ const isAbstract = (0, node_utils_1.hasModifier)(SyntaxKind.AbstractKeyword, node);
877
854
  /**
878
855
  * Unlike in object literal methods, class method params can have decorators
879
856
  */
@@ -929,8 +906,7 @@ class Converter {
929
906
  id: null,
930
907
  params: this.convertParameters(node.parameters),
931
908
  returnType: node.type && this.convertTypeAnnotation(node.type, node),
932
- typeParameters: node.typeParameters &&
933
- this.convertTSTypeParametersToTypeParametersDeclaration(node.typeParameters),
909
+ typeParameters: this.convertTypeParameters(node),
934
910
  });
935
911
  if (constructor.typeParameters) {
936
912
  this.fixParentLocation(constructor, constructor.typeParameters.range);
@@ -979,8 +955,7 @@ class Converter {
979
955
  id: this.convertChild(node.name),
980
956
  params: this.convertParameters(node.parameters),
981
957
  returnType: node.type && this.convertTypeAnnotation(node.type, node),
982
- typeParameters: node.typeParameters &&
983
- this.convertTSTypeParametersToTypeParametersDeclaration(node.typeParameters),
958
+ typeParameters: this.convertTypeParameters(node),
984
959
  });
985
960
  }
986
961
  case SyntaxKind.SuperKeyword:
@@ -1077,8 +1052,7 @@ class Converter {
1077
1052
  id: null,
1078
1053
  params: this.convertParameters(node.parameters),
1079
1054
  returnType: node.type && this.convertTypeAnnotation(node.type, node),
1080
- typeParameters: node.typeParameters &&
1081
- this.convertTSTypeParametersToTypeParametersDeclaration(node.typeParameters),
1055
+ typeParameters: this.convertTypeParameters(node),
1082
1056
  });
1083
1057
  }
1084
1058
  case SyntaxKind.YieldExpression:
@@ -1221,36 +1195,11 @@ class Converter {
1221
1195
  // Classes
1222
1196
  case SyntaxKind.ClassDeclaration:
1223
1197
  case SyntaxKind.ClassExpression: {
1224
- const heritageClauses = node.heritageClauses ?? [];
1225
1198
  const classNodeType = node.kind === SyntaxKind.ClassDeclaration
1226
1199
  ? ts_estree_1.AST_NODE_TYPES.ClassDeclaration
1227
1200
  : ts_estree_1.AST_NODE_TYPES.ClassExpression;
1228
- let extendsClause;
1229
- let implementsClause;
1230
- for (const heritageClause of heritageClauses) {
1231
- const { token, types } = heritageClause;
1232
- if (types.length === 0) {
1233
- this.#throwError(heritageClause, `'${ts.tokenToString(token)}' list cannot be empty.`);
1234
- }
1235
- if (token === SyntaxKind.ExtendsKeyword) {
1236
- if (extendsClause) {
1237
- this.#throwError(heritageClause, "'extends' clause already seen.");
1238
- }
1239
- if (implementsClause) {
1240
- this.#throwError(heritageClause, "'extends' clause must precede 'implements' clause.");
1241
- }
1242
- if (types.length > 1) {
1243
- this.#throwError(types[1], 'Classes can only extend a single class.');
1244
- }
1245
- extendsClause ??= heritageClause;
1246
- }
1247
- else if (token === SyntaxKind.ImplementsKeyword) {
1248
- if (implementsClause) {
1249
- this.#throwError(heritageClause, "'implements' clause already seen.");
1250
- }
1251
- implementsClause ??= heritageClause;
1252
- }
1253
- }
1201
+ const extendsClause = node.heritageClauses?.find(heritageClause => heritageClause.token === SyntaxKind.ExtendsKeyword);
1202
+ const implementsClause = node.heritageClauses?.find(heritageClause => heritageClause.token === SyntaxKind.ImplementsKeyword);
1254
1203
  const result = this.createNode(node, {
1255
1204
  type: classNodeType,
1256
1205
  abstract: (0, node_utils_1.hasModifier)(SyntaxKind.AbstractKeyword, node),
@@ -1267,8 +1216,7 @@ class Converter {
1267
1216
  ? this.convertChild(extendsClause.types[0].expression)
1268
1217
  : null,
1269
1218
  superTypeArguments: undefined,
1270
- typeParameters: node.typeParameters &&
1271
- this.convertTSTypeParametersToTypeParametersDeclaration(node.typeParameters),
1219
+ typeParameters: this.convertTypeParameters(node),
1272
1220
  });
1273
1221
  if (extendsClause?.types[0]?.typeArguments) {
1274
1222
  result.superTypeArguments = this.convertTypeArguments(extendsClause.types[0]);
@@ -1355,11 +1303,6 @@ class Converter {
1355
1303
  }
1356
1304
  case SyntaxKind.ExportSpecifier: {
1357
1305
  const local = node.propertyName ?? node.name;
1358
- if (local.kind === SyntaxKind.StringLiteral &&
1359
- parent.kind === SyntaxKind.ExportDeclaration &&
1360
- parent.moduleSpecifier?.kind !== SyntaxKind.StringLiteral) {
1361
- this.#throwError(local, 'A string literal cannot be used as a local exported binding without `from`.');
1362
- }
1363
1306
  return this.createNode(node, {
1364
1307
  type: ts_estree_1.AST_NODE_TYPES.ExportSpecifier,
1365
1308
  exported: this.convertChild(node.name),
@@ -1841,8 +1784,7 @@ class Converter {
1841
1784
  declare: (0, node_utils_1.hasModifier)(SyntaxKind.DeclareKeyword, node),
1842
1785
  id: this.convertChild(node.name),
1843
1786
  typeAnnotation: this.convertChild(node.type),
1844
- typeParameters: node.typeParameters &&
1845
- this.convertTSTypeParametersToTypeParametersDeclaration(node.typeParameters),
1787
+ typeParameters: this.convertTypeParameters(node),
1846
1788
  });
1847
1789
  return this.fixExports(node, result);
1848
1790
  }
@@ -1877,8 +1819,7 @@ class Converter {
1877
1819
  abstract: (0, node_utils_1.hasModifier)(SyntaxKind.AbstractKeyword, node),
1878
1820
  params: this.convertParameters(node.parameters),
1879
1821
  returnType: node.type && this.convertTypeAnnotation(node.type, node),
1880
- typeParameters: node.typeParameters &&
1881
- this.convertTSTypeParametersToTypeParametersDeclaration(node.typeParameters),
1822
+ typeParameters: this.convertTypeParameters(node),
1882
1823
  });
1883
1824
  }
1884
1825
  case SyntaxKind.FunctionType:
@@ -1893,8 +1834,7 @@ class Converter {
1893
1834
  type,
1894
1835
  params: this.convertParameters(node.parameters),
1895
1836
  returnType: node.type && this.convertTypeAnnotation(node.type, node),
1896
- typeParameters: node.typeParameters &&
1897
- this.convertTSTypeParametersToTypeParametersDeclaration(node.typeParameters),
1837
+ typeParameters: this.convertTypeParameters(node),
1898
1838
  });
1899
1839
  }
1900
1840
  case SyntaxKind.ExpressionWithTypeArguments: {
@@ -1911,27 +1851,14 @@ class Converter {
1911
1851
  });
1912
1852
  }
1913
1853
  case SyntaxKind.InterfaceDeclaration: {
1914
- const interfaceHeritageClauses = node.heritageClauses ?? [];
1915
- const interfaceExtends = [];
1916
- let seenExtendsClause = false;
1917
- for (const heritageClause of interfaceHeritageClauses) {
1918
- if (heritageClause.token !== SyntaxKind.ExtendsKeyword) {
1919
- this.#throwError(heritageClause, heritageClause.token === SyntaxKind.ImplementsKeyword
1920
- ? "Interface declaration cannot have 'implements' clause."
1921
- : 'Unexpected token.');
1922
- }
1923
- if (seenExtendsClause) {
1924
- this.#throwError(heritageClause, "'extends' clause already seen.");
1925
- }
1926
- seenExtendsClause = true;
1927
- for (const heritageType of heritageClause.types) {
1928
- if (!isEntityNameExpression(heritageType.expression) ||
1929
- ts.isOptionalChain(heritageType.expression)) {
1930
- this.#throwError(heritageType, 'Interface declaration can only extend an identifier/qualified name with optional type arguments.');
1931
- }
1932
- interfaceExtends.push(this.convertChild(heritageType, node));
1933
- }
1934
- }
1854
+ const interfaceExtends = node.heritageClauses?.flatMap(heritageClause =>
1855
+ // `InterfaceDeclaration` can only have `extends`,
1856
+ // already checked in `check-syntax-errors.ts`,
1857
+ // However, `allowInvalidAST` allow to bypass the syntax check,
1858
+ // We'll just ignore clauses after other keywords
1859
+ heritageClause.token === SyntaxKind.ExtendsKeyword
1860
+ ? heritageClause.types.map(heritageType => this.convertChild(heritageType, node))
1861
+ : []) ?? [];
1935
1862
  const result = this.createNode(node, {
1936
1863
  type: ts_estree_1.AST_NODE_TYPES.TSInterfaceDeclaration,
1937
1864
  body: this.createNode(node, {
@@ -1942,8 +1869,7 @@ class Converter {
1942
1869
  declare: (0, node_utils_1.hasModifier)(SyntaxKind.DeclareKeyword, node),
1943
1870
  extends: interfaceExtends,
1944
1871
  id: this.convertChild(node.name),
1945
- typeParameters: node.typeParameters &&
1946
- this.convertTSTypeParametersToTypeParametersDeclaration(node.typeParameters),
1872
+ typeParameters: this.convertTypeParameters(node),
1947
1873
  });
1948
1874
  return this.fixExports(node, result);
1949
1875
  }
@@ -2070,23 +1996,12 @@ class Converter {
2070
1996
  const result = this.createNode(node, {
2071
1997
  type: ts_estree_1.AST_NODE_TYPES.TSModuleDeclaration,
2072
1998
  ...(() => {
2073
- // the constraints checked by this function are syntactically enforced by TS
2074
- // the checks mostly exist for type's sake
2075
1999
  if (node.flags & ts.NodeFlags.GlobalAugmentation) {
2076
- const id = this.convertChild(node.name);
2077
- const body = this.convertChild(node.body);
2078
- if (body == null ||
2079
- body.type === ts_estree_1.AST_NODE_TYPES.TSModuleDeclaration) {
2080
- this.#throwError(node.body ?? node, 'Expected a valid module body');
2081
- }
2082
- if (id.type !== ts_estree_1.AST_NODE_TYPES.Identifier) {
2083
- this.#throwError(node.name, 'global module augmentation must have an Identifier id');
2084
- }
2085
2000
  return {
2086
- body: body,
2001
+ body: this.convertChild(node.body),
2087
2002
  declare: false,
2088
2003
  global: false,
2089
- id,
2004
+ id: this.convertChild(node.name),
2090
2005
  kind: 'global',
2091
2006
  };
2092
2007
  }
@@ -2103,12 +2018,6 @@ class Converter {
2103
2018
  // Nested module declarations are stored in TypeScript as nested tree nodes.
2104
2019
  // We "unravel" them here by making our own nested TSQualifiedName,
2105
2020
  // with the innermost node's body as the actual node body.
2106
- if (node.body == null) {
2107
- this.#throwError(node, 'Expected a module body');
2108
- }
2109
- if (node.name.kind !== ts.SyntaxKind.Identifier) {
2110
- this.#throwError(node.name, '`namespace`s must have an Identifier id');
2111
- }
2112
2021
  let name = this.createNode(node.name, {
2113
2022
  type: ts_estree_1.AST_NODE_TYPES.Identifier,
2114
2023
  range: [node.name.getStart(this.ast), node.name.getEnd()],
@@ -2352,7 +2261,8 @@ class Converter {
2352
2261
  if ('typeParameters' in node) {
2353
2262
  result.typeParameters =
2354
2263
  node.typeParameters && 'pos' in node.typeParameters
2355
- ? this.convertTSTypeParametersToTypeParametersDeclaration(node.typeParameters)
2264
+ ? // @ts-expect-error -- Fix me
2265
+ this.convertTypeParameters(node)
2356
2266
  : null;
2357
2267
  }
2358
2268
  const decorators = (0, getModifiers_1.getDecorators)(node);
@@ -184,5 +184,6 @@ export declare function isThisIdentifier(node: ts.Node | undefined): node is ts.
184
184
  export declare function isThisInTypeQuery(node: ts.Node): boolean;
185
185
  export declare function isValidAssignmentTarget(node: ts.Node): boolean;
186
186
  export declare function getNamespaceModifiers(node: ts.ModuleDeclaration): ts.Modifier[] | undefined;
187
- export declare function declarationNameToString(name: ts.Node, ast: ts.SourceFile): string;
187
+ export declare function declarationNameToString(node: ts.Node): string;
188
+ export declare function isEntityNameExpression(node: ts.Node): node is ts.EntityNameExpression;
188
189
  export {};
@@ -70,6 +70,7 @@ exports.isThisInTypeQuery = isThisInTypeQuery;
70
70
  exports.isValidAssignmentTarget = isValidAssignmentTarget;
71
71
  exports.getNamespaceModifiers = getNamespaceModifiers;
72
72
  exports.declarationNameToString = declarationNameToString;
73
+ exports.isEntityNameExpression = isEntityNameExpression;
73
74
  const ts = __importStar(require("typescript"));
74
75
  const getModifiers_1 = require("./getModifiers");
75
76
  const xhtml_entities_1 = require("./jsx/xhtml-entities");
@@ -657,7 +658,16 @@ function getNamespaceModifiers(node) {
657
658
  return modifiers;
658
659
  }
659
660
  // `ts.declarationNameToString`
660
- function declarationNameToString(name, ast) {
661
- const text = ast.text.slice(name.pos, name.end).trimStart();
661
+ function declarationNameToString(node) {
662
+ const text = node.getSourceFile().text.slice(node.pos, node.end).trimStart();
662
663
  return text || '(Missing)';
663
664
  }
665
+ function isPropertyAccessEntityNameExpression(node) {
666
+ return (ts.isPropertyAccessExpression(node) &&
667
+ ts.isIdentifier(node.name) &&
668
+ isEntityNameExpression(node.expression));
669
+ }
670
+ function isEntityNameExpression(node) {
671
+ return (node.kind === SyntaxKind.Identifier ||
672
+ isPropertyAccessEntityNameExpression(node));
673
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@typescript-eslint/typescript-estree",
3
- "version": "8.52.1-alpha.0",
3
+ "version": "8.52.1-alpha.10",
4
4
  "description": "A parser that converts TypeScript source code into an ESTree compatible form",
5
5
  "files": [
6
6
  "dist",
@@ -52,10 +52,10 @@
52
52
  "typecheck": "yarn run -BT nx typecheck"
53
53
  },
54
54
  "dependencies": {
55
- "@typescript-eslint/project-service": "8.52.1-alpha.0",
56
- "@typescript-eslint/tsconfig-utils": "8.52.1-alpha.0",
57
- "@typescript-eslint/types": "8.52.1-alpha.0",
58
- "@typescript-eslint/visitor-keys": "8.52.1-alpha.0",
55
+ "@typescript-eslint/project-service": "8.52.1-alpha.10",
56
+ "@typescript-eslint/tsconfig-utils": "8.52.1-alpha.10",
57
+ "@typescript-eslint/types": "8.52.1-alpha.10",
58
+ "@typescript-eslint/visitor-keys": "8.52.1-alpha.10",
59
59
  "debug": "^4.4.3",
60
60
  "minimatch": "^9.0.5",
61
61
  "semver": "^7.7.3",