esrap 2.1.0 → 2.1.1

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "esrap",
3
- "version": "2.1.0",
3
+ "version": "2.1.1",
4
4
  "description": "Parse in reverse",
5
5
  "repository": {
6
6
  "type": "git",
@@ -33,6 +33,7 @@
33
33
  "@vitest/ui": "^2.1.1",
34
34
  "acorn": "^8.15.0",
35
35
  "dts-buddy": "^0.6.2",
36
+ "oxc-parser": "^0.95.0",
36
37
  "prettier": "^3.0.3",
37
38
  "typescript": "^5.7.2",
38
39
  "vitest": "^2.1.1",
@@ -51,6 +52,8 @@
51
52
  "check": "tsc",
52
53
  "sandbox": "node test/sandbox/index.js",
53
54
  "test": "vitest --run",
54
- "test:ui": "vitest --ui"
55
+ "test:ui": "vitest --ui",
56
+ "format": "pnpm lint --write",
57
+ "lint": "prettier --check . --ignore-path .gitignore --ignore-path .prettierignore"
55
58
  }
56
59
  }
@@ -505,6 +505,8 @@ export default (options = {}) => {
505
505
  context.write('declare ');
506
506
  }
507
507
 
508
+ if (node.abstract) context.write('abstract ');
509
+
508
510
  context.write('class ');
509
511
 
510
512
  if (node.id) {
@@ -571,6 +573,130 @@ export default (options = {}) => {
571
573
  context.visit(node.body);
572
574
  },
573
575
 
576
+ /**
577
+ * @param {TSESTree.MethodDefinition | TSESTree.TSAbstractMethodDefinition} node
578
+ * @param {Context} context
579
+ */
580
+ 'MethodDefinition|TSAbstractMethodDefinition': (node, context) => {
581
+ if (node.decorators) {
582
+ for (const decorator of node.decorators) {
583
+ context.visit(decorator);
584
+ }
585
+ }
586
+
587
+ // @ts-expect-error `acorn-typescript` and `@typescript-eslint/types` have slightly different type definitions
588
+ if (node.abstract || node.type === 'TSAbstractMethodDefinition') {
589
+ context.write('abstract ');
590
+ }
591
+
592
+ if (node.static) {
593
+ context.write('static ');
594
+ }
595
+
596
+ if (node.kind === 'get' || node.kind === 'set') {
597
+ // Getter or setter
598
+ context.write(node.kind + ' ');
599
+ }
600
+
601
+ if (node.value.async) {
602
+ context.write('async ');
603
+ }
604
+
605
+ if (node.value.generator) {
606
+ context.write('*');
607
+ }
608
+
609
+ if (node.computed) context.write('[');
610
+ context.visit(node.key);
611
+ if (node.computed) context.write(']');
612
+
613
+ context.write('(');
614
+ sequence(
615
+ context,
616
+ node.value.params,
617
+ (node.value.returnType ?? node.value.body)?.loc?.start ?? node.loc?.end ?? null,
618
+ false
619
+ );
620
+ context.write(')');
621
+
622
+ if (node.value.returnType) context.visit(node.value.returnType);
623
+
624
+ context.write(' ');
625
+
626
+ if (node.value.body) context.visit(node.value.body);
627
+ },
628
+
629
+ /**
630
+ * @param {TSESTree.PropertyDefinition | TSESTree.TSAbstractPropertyDefinition | TSESTree.AccessorProperty | TSESTree.TSAbstractAccessorProperty} node
631
+ * @param {Context} context
632
+ */
633
+ 'PropertyDefinition|TSAbstractPropertyDefinition|AccessorProperty|TSAbstractAccessorProperty': (
634
+ node,
635
+ context
636
+ ) => {
637
+ if (node.decorators) {
638
+ for (const decorator of node.decorators) {
639
+ context.visit(decorator);
640
+ }
641
+ }
642
+
643
+ if (node.accessibility) {
644
+ context.write(node.accessibility + ' ');
645
+ }
646
+
647
+ if (
648
+ // @ts-expect-error `acorn-typescript` and `@typescript-eslint/types` have slightly different type definitions
649
+ node.abstract ||
650
+ node.type === 'TSAbstractPropertyDefinition' ||
651
+ node.type === 'TSAbstractAccessorProperty'
652
+ ) {
653
+ context.write('abstract ');
654
+ }
655
+
656
+ if (node.static) {
657
+ context.write('static ');
658
+ }
659
+
660
+ if (
661
+ // @ts-expect-error `acorn-typescript` and `@typescript-eslint/types` have slightly different type definitions
662
+ node.accessor ||
663
+ node.type === 'AccessorProperty' ||
664
+ node.type === 'TSAbstractAccessorProperty'
665
+ ) {
666
+ context.write('accessor ');
667
+ }
668
+
669
+ if (node.computed) {
670
+ context.write('[');
671
+ context.visit(node.key);
672
+ context.write(']');
673
+ } else {
674
+ context.visit(node.key);
675
+ }
676
+
677
+ if (node.typeAnnotation) {
678
+ if (node.type === 'AccessorProperty' || node.type === 'TSAbstractAccessorProperty') {
679
+ context.visit(node.typeAnnotation);
680
+ } else {
681
+ context.write(': ');
682
+ context.visit(node.typeAnnotation.typeAnnotation);
683
+ }
684
+ }
685
+
686
+ if (node.value) {
687
+ context.write(' = ');
688
+ context.visit(node.value);
689
+ }
690
+
691
+ context.write(';');
692
+
693
+ flush_trailing_comments(
694
+ context,
695
+ (node.value ?? node.typeAnnotation ?? node.key).loc?.end ?? null,
696
+ null
697
+ );
698
+ },
699
+
574
700
  /**
575
701
  * @param {TSESTree.RestElement | TSESTree.SpreadElement} node
576
702
  * @param {Context} context
@@ -581,6 +707,63 @@ export default (options = {}) => {
581
707
 
582
708
  // @ts-expect-error `acorn-typescript` and `@typescript-eslint/types` have slightly different type definitions
583
709
  if (node.typeAnnotation) context.visit(node.typeAnnotation);
710
+ },
711
+
712
+ /**
713
+ * @param {TSESTree.TSConstructSignatureDeclaration | TSESTree.TSCallSignatureDeclaration} node
714
+ * @param {Context} context
715
+ */
716
+ 'TSConstructSignatureDeclaration|TSCallSignatureDeclaration': (node, context) => {
717
+ if (node.type === 'TSConstructSignatureDeclaration') context.write('new');
718
+
719
+ if (node.typeParameters) {
720
+ context.visit(node.typeParameters);
721
+ }
722
+
723
+ context.write('(');
724
+
725
+ sequence(
726
+ context,
727
+ // @ts-expect-error `acorn-typescript` and `@typescript-eslint/types` have slightly different type definitions
728
+ node.parameters ?? node.params,
729
+ // @ts-expect-error `acorn-typescript` and `@typescript-eslint/types` have slightly different type definitions
730
+ (node.typeAnnotation ?? node.returnType)?.loc?.start ?? null,
731
+ false
732
+ );
733
+ context.write(')');
734
+
735
+ // @ts-expect-error `acorn-typescript` and `@typescript-eslint/types` have slightly different type definitions
736
+ if (node.typeAnnotation || node.returnType) {
737
+ // @ts-expect-error `acorn-typescript` and `@typescript-eslint/types` have slightly different type definitions
738
+ context.visit(node.typeAnnotation ?? node.returnType);
739
+ }
740
+ },
741
+
742
+ /**
743
+ * @param {TSESTree.TSFunctionType | TSESTree.TSConstructorType} node
744
+ * @param {Context} context
745
+ */
746
+ 'TSFunctionType|TSConstructorType': (node, context) => {
747
+ if (node.type === 'TSConstructorType') context.write('new ');
748
+ if (node.typeParameters) context.visit(node.typeParameters);
749
+
750
+ context.write('(');
751
+
752
+ sequence(
753
+ context,
754
+ // @ts-expect-error `acorn-typescript` and `@typescript-eslint/types` have slightly different type definitions
755
+ node.parameters ?? node.params,
756
+ // @ts-expect-error `acorn-typescript` and `@typescript-eslint/types` have slightly different type definitions
757
+ node.typeAnnotation?.typeAnnotation?.loc?.start ??
758
+ node.returnType?.typeAnnotation?.loc?.start ??
759
+ null,
760
+ false
761
+ );
762
+
763
+ context.write(') => ');
764
+
765
+ // @ts-expect-error `acorn-typescript` and `@typescript-eslint/types` have slightly different type definitions
766
+ context.visit(node.typeAnnotation?.typeAnnotation ?? node.returnType?.typeAnnotation);
584
767
  }
585
768
  };
586
769
 
@@ -593,6 +776,11 @@ export default (options = {}) => {
593
776
  visit(node);
594
777
  },
595
778
 
779
+ AccessorProperty:
780
+ shared[
781
+ 'PropertyDefinition|TSAbstractPropertyDefinition|AccessorProperty|TSAbstractAccessorProperty'
782
+ ],
783
+
596
784
  ArrayExpression: shared['ArrayExpression|ArrayPattern'],
597
785
 
598
786
  ArrayPattern: shared['ArrayExpression|ArrayPattern'],
@@ -798,7 +986,11 @@ export default (options = {}) => {
798
986
 
799
987
  context.visit(node.local);
800
988
 
801
- if (node.local.name !== node.exported.name) {
989
+ if (
990
+ node.local.type === 'Identifier' &&
991
+ node.exported.type === 'Identifier' &&
992
+ node.local.name !== node.exported.name
993
+ ) {
802
994
  context.write(' as ');
803
995
  context.visit(node.exported);
804
996
  }
@@ -945,11 +1137,19 @@ export default (options = {}) => {
945
1137
  context.visit(node.arguments[index]);
946
1138
  }
947
1139
  }
1140
+ if (node.options) {
1141
+ context.write(', ');
1142
+ context.visit(node.options);
1143
+ }
948
1144
  context.write(')');
949
1145
  },
950
1146
 
951
1147
  ImportSpecifier(node, context) {
952
- if (node.local.name !== node.imported.name) {
1148
+ if (
1149
+ node.local.type === 'Identifier' &&
1150
+ node.imported.type === 'Identifier' &&
1151
+ node.local.name !== node.imported.name
1152
+ ) {
953
1153
  context.visit(node.imported);
954
1154
  context.write(' as ');
955
1155
  }
@@ -1005,49 +1205,7 @@ export default (options = {}) => {
1005
1205
  context.visit(node.property);
1006
1206
  },
1007
1207
 
1008
- MethodDefinition(node, context) {
1009
- if (node.decorators) {
1010
- for (const decorator of node.decorators) {
1011
- context.visit(decorator);
1012
- }
1013
- }
1014
-
1015
- if (node.static) {
1016
- context.write('static ');
1017
- }
1018
-
1019
- if (node.kind === 'get' || node.kind === 'set') {
1020
- // Getter or setter
1021
- context.write(node.kind + ' ');
1022
- }
1023
-
1024
- if (node.value.async) {
1025
- context.write('async ');
1026
- }
1027
-
1028
- if (node.value.generator) {
1029
- context.write('*');
1030
- }
1031
-
1032
- if (node.computed) context.write('[');
1033
- context.visit(node.key);
1034
- if (node.computed) context.write(']');
1035
-
1036
- context.write('(');
1037
- sequence(
1038
- context,
1039
- node.value.params,
1040
- (node.value.returnType ?? node.value.body)?.loc?.start ?? node.loc?.end ?? null,
1041
- false
1042
- );
1043
- context.write(')');
1044
-
1045
- if (node.value.returnType) context.visit(node.value.returnType);
1046
-
1047
- context.write(' ');
1048
-
1049
- if (node.value.body) context.visit(node.value.body);
1050
- },
1208
+ MethodDefinition: shared['MethodDefinition|TSAbstractMethodDefinition'],
1051
1209
 
1052
1210
  NewExpression: shared['CallExpression|NewExpression'],
1053
1211
 
@@ -1067,7 +1225,9 @@ export default (options = {}) => {
1067
1225
 
1068
1226
  // @ts-expect-error this isn't a real node type, but Acorn produces it
1069
1227
  ParenthesizedExpression(node, context) {
1070
- return context.visit(node.expression);
1228
+ context.write('(');
1229
+ context.visit(node.expression);
1230
+ context.write(')');
1071
1231
  },
1072
1232
 
1073
1233
  PrivateIdentifier(node, context) {
@@ -1124,47 +1284,10 @@ export default (options = {}) => {
1124
1284
  }
1125
1285
  },
1126
1286
 
1127
- PropertyDefinition(node, context) {
1128
- if (node.decorators) {
1129
- for (const decorator of node.decorators) {
1130
- context.visit(decorator);
1131
- }
1132
- }
1133
-
1134
- if (node.accessibility) {
1135
- context.write(node.accessibility + ' ');
1136
- }
1137
-
1138
- if (node.static) {
1139
- context.write('static ');
1140
- }
1141
-
1142
- if (node.computed) {
1143
- context.write('[');
1144
- context.visit(node.key);
1145
- context.write(']');
1146
- } else {
1147
- context.visit(node.key);
1148
- }
1149
-
1150
- if (node.typeAnnotation) {
1151
- context.write(': ');
1152
- context.visit(node.typeAnnotation.typeAnnotation);
1153
- }
1154
-
1155
- if (node.value) {
1156
- context.write(' = ');
1157
- context.visit(node.value);
1158
- }
1159
-
1160
- context.write(';');
1161
-
1162
- flush_trailing_comments(
1163
- context,
1164
- (node.value ?? node.typeAnnotation ?? node.key).loc?.end ?? null,
1165
- null
1166
- );
1167
- },
1287
+ PropertyDefinition:
1288
+ shared[
1289
+ 'PropertyDefinition|TSAbstractPropertyDefinition|AccessorProperty|TSAbstractAccessorProperty'
1290
+ ],
1168
1291
 
1169
1292
  RestElement: shared['RestElement|SpreadElement'],
1170
1293
 
@@ -1369,6 +1492,18 @@ export default (options = {}) => {
1369
1492
  }
1370
1493
  },
1371
1494
 
1495
+ TSAbstractMethodDefinition: shared['MethodDefinition|TSAbstractMethodDefinition'],
1496
+
1497
+ TSAbstractAccessorProperty:
1498
+ shared[
1499
+ 'PropertyDefinition|TSAbstractPropertyDefinition|AccessorProperty|TSAbstractAccessorProperty'
1500
+ ],
1501
+
1502
+ TSAbstractPropertyDefinition:
1503
+ shared[
1504
+ 'PropertyDefinition|TSAbstractPropertyDefinition|AccessorProperty|TSAbstractAccessorProperty'
1505
+ ],
1506
+
1372
1507
  TSDeclareFunction(node, context) {
1373
1508
  context.write('declare ');
1374
1509
 
@@ -1442,6 +1577,18 @@ export default (options = {}) => {
1442
1577
  context.write('undefined', node);
1443
1578
  },
1444
1579
 
1580
+ TSObjectKeyword(node, context) {
1581
+ context.write('object', node);
1582
+ },
1583
+
1584
+ TSBigIntKeyword(node, context) {
1585
+ context.write('bigint', node);
1586
+ },
1587
+
1588
+ TSIntrinsicKeyword(node, context) {
1589
+ context.write('intrinsic', node);
1590
+ },
1591
+
1445
1592
  TSArrayType(node, context) {
1446
1593
  context.visit(node.elementType);
1447
1594
  context.write('[]');
@@ -1472,11 +1619,70 @@ export default (options = {}) => {
1472
1619
  }
1473
1620
  },
1474
1621
 
1622
+ TSTypeOperator(node, context) {
1623
+ context.write(node.operator + ' ');
1624
+ if (node.typeAnnotation) {
1625
+ context.visit(node.typeAnnotation);
1626
+ }
1627
+ },
1628
+
1629
+ TSTemplateLiteralType(node, context) {
1630
+ context.write('`');
1631
+ const { quasis, types } = node;
1632
+ for (let i = 0; i < types.length; i++) {
1633
+ const raw = quasis[i].value.raw;
1634
+
1635
+ context.write(raw + '${');
1636
+ context.visit(types[i]);
1637
+ context.write('}');
1638
+
1639
+ if (/\n/.test(raw)) context.multiline = true;
1640
+ }
1641
+ context.write('`');
1642
+ },
1643
+
1644
+ TSParameterProperty(node, context) {
1645
+ if (node.accessibility) {
1646
+ context.write(node.accessibility + ' ');
1647
+ }
1648
+
1649
+ if (node.readonly) {
1650
+ context.write('readonly ');
1651
+ }
1652
+
1653
+ context.visit(node.parameter);
1654
+ },
1655
+
1656
+ TSExportAssignment(node, context) {
1657
+ context.write('export = ');
1658
+ context.visit(node.expression);
1659
+ context.write(';');
1660
+ },
1661
+
1662
+ TSNamespaceExportDeclaration(node, context) {
1663
+ context.write('export as namespace ');
1664
+ context.visit(node.id);
1665
+ context.write(';');
1666
+ },
1667
+
1475
1668
  //@ts-expect-error I don't know why, but this is relied upon in the tests, but doesn't exist in the TSESTree types
1476
1669
  TSExpressionWithTypeArguments(node, context) {
1477
1670
  context.visit(node.expression);
1478
1671
  },
1479
1672
 
1673
+ TSTypeAssertion(node, context) {
1674
+ context.write('<');
1675
+ context.visit(node.typeAnnotation);
1676
+ context.write('>');
1677
+ if (EXPRESSIONS_PRECEDENCE[node.expression.type] < EXPRESSIONS_PRECEDENCE.TSTypeAssertion) {
1678
+ context.write('(');
1679
+ context.visit(node.expression);
1680
+ context.write(')');
1681
+ } else {
1682
+ context.visit(node.expression);
1683
+ }
1684
+ },
1685
+
1480
1686
  TSTypeParameterInstantiation(node, context) {
1481
1687
  context.write('<');
1482
1688
  for (let i = 0; i < node.params.length; i++) {
@@ -1496,8 +1702,9 @@ export default (options = {}) => {
1496
1702
  },
1497
1703
 
1498
1704
  TSTypeParameter(node, context) {
1705
+ if (node.name && node.name.type) context.visit(node.name);
1499
1706
  // @ts-expect-error type mismatch TSESTree and acorn-typescript?
1500
- context.write(node.name, node);
1707
+ else context.write(node.name, node);
1501
1708
 
1502
1709
  if (node.constraint) {
1503
1710
  context.write(' extends ');
@@ -1505,11 +1712,35 @@ export default (options = {}) => {
1505
1712
  }
1506
1713
  },
1507
1714
 
1715
+ TSTypePredicate(node, context) {
1716
+ if (node.parameterName) {
1717
+ context.visit(node.parameterName);
1718
+ } else if (node.typeAnnotation) {
1719
+ context.visit(node.typeAnnotation);
1720
+ }
1721
+
1722
+ if (node.asserts) {
1723
+ context.write(' asserts ');
1724
+ } else {
1725
+ context.write(' is ');
1726
+ }
1727
+
1728
+ if (node.typeAnnotation) {
1729
+ context.visit(node.typeAnnotation.typeAnnotation);
1730
+ }
1731
+ },
1732
+
1508
1733
  TSTypeQuery(node, context) {
1509
1734
  context.write('typeof ');
1510
1735
  context.visit(node.exprName);
1511
1736
  },
1512
1737
 
1738
+ TSClassImplements(node, context) {
1739
+ if (node.expression) {
1740
+ context.visit(node.expression);
1741
+ }
1742
+ },
1743
+
1513
1744
  TSEnumMember(node, context) {
1514
1745
  context.visit(node.id);
1515
1746
  if (node.initializer) {
@@ -1518,25 +1749,7 @@ export default (options = {}) => {
1518
1749
  }
1519
1750
  },
1520
1751
 
1521
- TSFunctionType(node, context) {
1522
- if (node.typeParameters) context.visit(node.typeParameters);
1523
-
1524
- context.write('(');
1525
-
1526
- sequence(
1527
- context,
1528
- // @ts-expect-error `acorn-typescript` and `@typescript-eslint/types` have slightly different type definitions
1529
- node.parameters,
1530
- // @ts-expect-error `acorn-typescript` and `@typescript-eslint/types` have slightly different type definitions
1531
- node.typeAnnotation.typeAnnotation.loc?.start ?? null,
1532
- false
1533
- );
1534
-
1535
- context.write(') => ');
1536
-
1537
- // @ts-expect-error `acorn-typescript` and `@typescript-eslint/types` have slightly different type definitions
1538
- context.visit(node.typeAnnotation.typeAnnotation);
1539
- },
1752
+ TSFunctionType: shared['TSFunctionType|TSConstructorType'],
1540
1753
 
1541
1754
  TSIndexSignature(node, context) {
1542
1755
  context.write('[');
@@ -1549,17 +1762,45 @@ export default (options = {}) => {
1549
1762
  context.visit(node.typeAnnotation);
1550
1763
  },
1551
1764
 
1765
+ TSMappedType(node, context) {
1766
+ context.write('{[');
1767
+
1768
+ if (node.typeParameter) {
1769
+ context.visit(node.typeParameter);
1770
+ } else {
1771
+ context.visit(node.key);
1772
+ context.write(' in ');
1773
+ context.visit(node.constraint);
1774
+ }
1775
+
1776
+ context.write(']');
1777
+ if (node.typeAnnotation) {
1778
+ context.write(': ');
1779
+ context.visit(node.typeAnnotation);
1780
+ }
1781
+ context.write('}');
1782
+ },
1783
+
1552
1784
  TSMethodSignature(node, context) {
1553
1785
  context.visit(node.key);
1554
1786
 
1555
1787
  context.write('(');
1556
1788
 
1557
- // @ts-expect-error `acorn-typescript` and `@typescript-eslint/types` have slightly different type definitions
1558
- sequence(context, node.parameters, node.typeAnnotation.loc?.start ?? null, false);
1789
+ sequence(
1790
+ context,
1791
+ // @ts-expect-error `acorn-typescript` and `@typescript-eslint/types` have slightly different type definitions
1792
+ node.parameters ?? node.params,
1793
+ // @ts-expect-error `acorn-typescript` and `@typescript-eslint/types` have slightly different type definitions
1794
+ (node.typeAnnotation ?? node.returnType)?.loc?.start ?? null,
1795
+ false
1796
+ );
1559
1797
  context.write(')');
1560
1798
 
1561
1799
  // @ts-expect-error `acorn-typescript` and `@typescript-eslint/types` have slightly different type definitions
1562
- context.visit(node.typeAnnotation);
1800
+ if (node.typeAnnotation || node.returnType) {
1801
+ // @ts-expect-error `acorn-typescript` and `@typescript-eslint/types` have slightly different type definitions
1802
+ context.visit(node.typeAnnotation ?? node.returnType);
1803
+ }
1563
1804
  },
1564
1805
 
1565
1806
  TSTupleType(node, context) {
@@ -1582,10 +1823,18 @@ export default (options = {}) => {
1582
1823
  sequence(context, node.types, node.loc?.end ?? null, false, ' &');
1583
1824
  },
1584
1825
 
1826
+ TSInferType(node, context) {
1827
+ context.write('infer ');
1828
+ context.visit(node.typeParameter);
1829
+ },
1830
+
1585
1831
  TSLiteralType(node, context) {
1586
1832
  context.visit(node.literal);
1587
1833
  },
1588
1834
 
1835
+ TSCallSignatureDeclaration:
1836
+ shared['TSConstructSignatureDeclaration|TSCallSignatureDeclaration'],
1837
+
1589
1838
  TSConditionalType(node, context) {
1590
1839
  context.visit(node.checkType);
1591
1840
  context.write(' extends ');
@@ -1596,6 +1845,17 @@ export default (options = {}) => {
1596
1845
  context.visit(node.falseType);
1597
1846
  },
1598
1847
 
1848
+ TSConstructSignatureDeclaration:
1849
+ shared['TSConstructSignatureDeclaration|TSCallSignatureDeclaration'],
1850
+
1851
+ TSConstructorType: shared['TSFunctionType|TSConstructorType'],
1852
+
1853
+ TSExternalModuleReference(node, context) {
1854
+ context.write('require(');
1855
+ context.visit(node.expression);
1856
+ context.write(');');
1857
+ },
1858
+
1599
1859
  TSIndexedAccessType(node, context) {
1600
1860
  context.visit(node.objectType);
1601
1861
  context.write('[');
@@ -1603,6 +1863,13 @@ export default (options = {}) => {
1603
1863
  context.write(']');
1604
1864
  },
1605
1865
 
1866
+ TSImportEqualsDeclaration(node, context) {
1867
+ context.write('import ');
1868
+ context.visit(node.id);
1869
+ context.write(' = ');
1870
+ context.visit(node.moduleReference);
1871
+ },
1872
+
1606
1873
  TSImportType(node, context) {
1607
1874
  context.write('import(');
1608
1875
  context.visit(node.argument);
@@ -1614,6 +1881,20 @@ export default (options = {}) => {
1614
1881
  }
1615
1882
  },
1616
1883
 
1884
+ TSOptionalType(node, context) {
1885
+ context.visit(node.typeAnnotation);
1886
+ context.write('?');
1887
+ },
1888
+
1889
+ TSRestType(node, context) {
1890
+ context.write('...');
1891
+ context.visit(node.typeAnnotation);
1892
+ },
1893
+
1894
+ TSThisType(node, context) {
1895
+ context.write('this', node);
1896
+ },
1897
+
1617
1898
  TSAsExpression(node, context) {
1618
1899
  if (node.expression) {
1619
1900
  const needs_parens =
@@ -1637,7 +1918,7 @@ export default (options = {}) => {
1637
1918
  context.write(' {');
1638
1919
  context.indent();
1639
1920
  context.newline();
1640
- sequence(context, node.members, node.loc?.end ?? null, false);
1921
+ sequence(context, node.members ?? node.body.members, node.loc?.end ?? null, false);
1641
1922
  context.dedent();
1642
1923
  context.newline();
1643
1924
  context.write('}');
@@ -1676,7 +1957,7 @@ export default (options = {}) => {
1676
1957
  context.write('interface ');
1677
1958
  context.visit(node.id);
1678
1959
  if (node.typeParameters) context.visit(node.typeParameters);
1679
- if (node.extends) {
1960
+ if (node.extends && node.extends.length > 0) {
1680
1961
  context.write(' extends ');
1681
1962
  sequence(context, node.extends, node.body.loc?.start ?? null, false);
1682
1963
  }
@@ -1685,6 +1966,24 @@ export default (options = {}) => {
1685
1966
  context.write('}');
1686
1967
  },
1687
1968
 
1969
+ TSInstantiationExpression(node, context) {
1970
+ context.visit(node.expression);
1971
+ context.visit(node.typeArguments);
1972
+ },
1973
+
1974
+ TSInterfaceHeritage(node, context) {
1975
+ if (node.expression) {
1976
+ context.visit(node.expression);
1977
+ }
1978
+ },
1979
+
1980
+ //@ts-expect-error I don't know why, but this is relied upon in the tests, but doesn't exist in the TSESTree types
1981
+ TSParenthesizedType(node, context) {
1982
+ context.write('(');
1983
+ context.visit(node.typeAnnotation);
1984
+ context.write(')');
1985
+ },
1986
+
1688
1987
  TSSatisfiesExpression(node, context) {
1689
1988
  if (node.expression) {
1690
1989
  const needs_parens =