esrap 2.1.0 → 2.1.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "esrap",
3
- "version": "2.1.0",
3
+ "version": "2.1.2",
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
  }
@@ -501,10 +501,18 @@ export default (options = {}) => {
501
501
  * @param {Context} context
502
502
  */
503
503
  'ClassDeclaration|ClassExpression': (node, context) => {
504
+ if (node.decorators) {
505
+ for (const decorator of node.decorators) {
506
+ context.visit(decorator);
507
+ }
508
+ }
509
+
504
510
  if (node.declare) {
505
511
  context.write('declare ');
506
512
  }
507
513
 
514
+ if (node.abstract) context.write('abstract ');
515
+
508
516
  context.write('class ');
509
517
 
510
518
  if (node.id) {
@@ -571,6 +579,130 @@ export default (options = {}) => {
571
579
  context.visit(node.body);
572
580
  },
573
581
 
582
+ /**
583
+ * @param {TSESTree.MethodDefinition | TSESTree.TSAbstractMethodDefinition} node
584
+ * @param {Context} context
585
+ */
586
+ 'MethodDefinition|TSAbstractMethodDefinition': (node, context) => {
587
+ if (node.decorators) {
588
+ for (const decorator of node.decorators) {
589
+ context.visit(decorator);
590
+ }
591
+ }
592
+
593
+ // @ts-expect-error `acorn-typescript` and `@typescript-eslint/types` have slightly different type definitions
594
+ if (node.abstract || node.type === 'TSAbstractMethodDefinition') {
595
+ context.write('abstract ');
596
+ }
597
+
598
+ if (node.static) {
599
+ context.write('static ');
600
+ }
601
+
602
+ if (node.kind === 'get' || node.kind === 'set') {
603
+ // Getter or setter
604
+ context.write(node.kind + ' ');
605
+ }
606
+
607
+ if (node.value.async) {
608
+ context.write('async ');
609
+ }
610
+
611
+ if (node.value.generator) {
612
+ context.write('*');
613
+ }
614
+
615
+ if (node.computed) context.write('[');
616
+ context.visit(node.key);
617
+ if (node.computed) context.write(']');
618
+
619
+ context.write('(');
620
+ sequence(
621
+ context,
622
+ node.value.params,
623
+ (node.value.returnType ?? node.value.body)?.loc?.start ?? node.loc?.end ?? null,
624
+ false
625
+ );
626
+ context.write(')');
627
+
628
+ if (node.value.returnType) context.visit(node.value.returnType);
629
+
630
+ context.write(' ');
631
+
632
+ if (node.value.body) context.visit(node.value.body);
633
+ },
634
+
635
+ /**
636
+ * @param {TSESTree.PropertyDefinition | TSESTree.TSAbstractPropertyDefinition | TSESTree.AccessorProperty | TSESTree.TSAbstractAccessorProperty} node
637
+ * @param {Context} context
638
+ */
639
+ 'PropertyDefinition|TSAbstractPropertyDefinition|AccessorProperty|TSAbstractAccessorProperty': (
640
+ node,
641
+ context
642
+ ) => {
643
+ if (node.decorators) {
644
+ for (const decorator of node.decorators) {
645
+ context.visit(decorator);
646
+ }
647
+ }
648
+
649
+ if (node.accessibility) {
650
+ context.write(node.accessibility + ' ');
651
+ }
652
+
653
+ if (
654
+ // @ts-expect-error `acorn-typescript` and `@typescript-eslint/types` have slightly different type definitions
655
+ node.abstract ||
656
+ node.type === 'TSAbstractPropertyDefinition' ||
657
+ node.type === 'TSAbstractAccessorProperty'
658
+ ) {
659
+ context.write('abstract ');
660
+ }
661
+
662
+ if (node.static) {
663
+ context.write('static ');
664
+ }
665
+
666
+ if (
667
+ // @ts-expect-error `acorn-typescript` and `@typescript-eslint/types` have slightly different type definitions
668
+ node.accessor ||
669
+ node.type === 'AccessorProperty' ||
670
+ node.type === 'TSAbstractAccessorProperty'
671
+ ) {
672
+ context.write('accessor ');
673
+ }
674
+
675
+ if (node.computed) {
676
+ context.write('[');
677
+ context.visit(node.key);
678
+ context.write(']');
679
+ } else {
680
+ context.visit(node.key);
681
+ }
682
+
683
+ if (node.typeAnnotation) {
684
+ if (node.type === 'AccessorProperty' || node.type === 'TSAbstractAccessorProperty') {
685
+ context.visit(node.typeAnnotation);
686
+ } else {
687
+ context.write(': ');
688
+ context.visit(node.typeAnnotation.typeAnnotation);
689
+ }
690
+ }
691
+
692
+ if (node.value) {
693
+ context.write(' = ');
694
+ context.visit(node.value);
695
+ }
696
+
697
+ context.write(';');
698
+
699
+ flush_trailing_comments(
700
+ context,
701
+ (node.value ?? node.typeAnnotation ?? node.key).loc?.end ?? null,
702
+ null
703
+ );
704
+ },
705
+
574
706
  /**
575
707
  * @param {TSESTree.RestElement | TSESTree.SpreadElement} node
576
708
  * @param {Context} context
@@ -581,6 +713,63 @@ export default (options = {}) => {
581
713
 
582
714
  // @ts-expect-error `acorn-typescript` and `@typescript-eslint/types` have slightly different type definitions
583
715
  if (node.typeAnnotation) context.visit(node.typeAnnotation);
716
+ },
717
+
718
+ /**
719
+ * @param {TSESTree.TSConstructSignatureDeclaration | TSESTree.TSCallSignatureDeclaration} node
720
+ * @param {Context} context
721
+ */
722
+ 'TSConstructSignatureDeclaration|TSCallSignatureDeclaration': (node, context) => {
723
+ if (node.type === 'TSConstructSignatureDeclaration') context.write('new');
724
+
725
+ if (node.typeParameters) {
726
+ context.visit(node.typeParameters);
727
+ }
728
+
729
+ context.write('(');
730
+
731
+ sequence(
732
+ context,
733
+ // @ts-expect-error `acorn-typescript` and `@typescript-eslint/types` have slightly different type definitions
734
+ node.parameters ?? node.params,
735
+ // @ts-expect-error `acorn-typescript` and `@typescript-eslint/types` have slightly different type definitions
736
+ (node.typeAnnotation ?? node.returnType)?.loc?.start ?? null,
737
+ false
738
+ );
739
+ context.write(')');
740
+
741
+ // @ts-expect-error `acorn-typescript` and `@typescript-eslint/types` have slightly different type definitions
742
+ if (node.typeAnnotation || node.returnType) {
743
+ // @ts-expect-error `acorn-typescript` and `@typescript-eslint/types` have slightly different type definitions
744
+ context.visit(node.typeAnnotation ?? node.returnType);
745
+ }
746
+ },
747
+
748
+ /**
749
+ * @param {TSESTree.TSFunctionType | TSESTree.TSConstructorType} node
750
+ * @param {Context} context
751
+ */
752
+ 'TSFunctionType|TSConstructorType': (node, context) => {
753
+ if (node.type === 'TSConstructorType') context.write('new ');
754
+ if (node.typeParameters) context.visit(node.typeParameters);
755
+
756
+ context.write('(');
757
+
758
+ sequence(
759
+ context,
760
+ // @ts-expect-error `acorn-typescript` and `@typescript-eslint/types` have slightly different type definitions
761
+ node.parameters ?? node.params,
762
+ // @ts-expect-error `acorn-typescript` and `@typescript-eslint/types` have slightly different type definitions
763
+ node.typeAnnotation?.typeAnnotation?.loc?.start ??
764
+ node.returnType?.typeAnnotation?.loc?.start ??
765
+ null,
766
+ false
767
+ );
768
+
769
+ context.write(') => ');
770
+
771
+ // @ts-expect-error `acorn-typescript` and `@typescript-eslint/types` have slightly different type definitions
772
+ context.visit(node.typeAnnotation?.typeAnnotation ?? node.returnType?.typeAnnotation);
584
773
  }
585
774
  };
586
775
 
@@ -593,6 +782,11 @@ export default (options = {}) => {
593
782
  visit(node);
594
783
  },
595
784
 
785
+ AccessorProperty:
786
+ shared[
787
+ 'PropertyDefinition|TSAbstractPropertyDefinition|AccessorProperty|TSAbstractAccessorProperty'
788
+ ],
789
+
596
790
  ArrayExpression: shared['ArrayExpression|ArrayPattern'],
597
791
 
598
792
  ArrayPattern: shared['ArrayExpression|ArrayPattern'],
@@ -798,7 +992,11 @@ export default (options = {}) => {
798
992
 
799
993
  context.visit(node.local);
800
994
 
801
- if (node.local.name !== node.exported.name) {
995
+ if (
996
+ node.local.type === 'Identifier' &&
997
+ node.exported.type === 'Identifier' &&
998
+ node.local.name !== node.exported.name
999
+ ) {
802
1000
  context.write(' as ');
803
1001
  context.visit(node.exported);
804
1002
  }
@@ -945,11 +1143,19 @@ export default (options = {}) => {
945
1143
  context.visit(node.arguments[index]);
946
1144
  }
947
1145
  }
1146
+ if (node.options) {
1147
+ context.write(', ');
1148
+ context.visit(node.options);
1149
+ }
948
1150
  context.write(')');
949
1151
  },
950
1152
 
951
1153
  ImportSpecifier(node, context) {
952
- if (node.local.name !== node.imported.name) {
1154
+ if (
1155
+ node.local.type === 'Identifier' &&
1156
+ node.imported.type === 'Identifier' &&
1157
+ node.local.name !== node.imported.name
1158
+ ) {
953
1159
  context.visit(node.imported);
954
1160
  context.write(' as ');
955
1161
  }
@@ -1005,49 +1211,7 @@ export default (options = {}) => {
1005
1211
  context.visit(node.property);
1006
1212
  },
1007
1213
 
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
- },
1214
+ MethodDefinition: shared['MethodDefinition|TSAbstractMethodDefinition'],
1051
1215
 
1052
1216
  NewExpression: shared['CallExpression|NewExpression'],
1053
1217
 
@@ -1067,7 +1231,9 @@ export default (options = {}) => {
1067
1231
 
1068
1232
  // @ts-expect-error this isn't a real node type, but Acorn produces it
1069
1233
  ParenthesizedExpression(node, context) {
1070
- return context.visit(node.expression);
1234
+ context.write('(');
1235
+ context.visit(node.expression);
1236
+ context.write(')');
1071
1237
  },
1072
1238
 
1073
1239
  PrivateIdentifier(node, context) {
@@ -1124,47 +1290,10 @@ export default (options = {}) => {
1124
1290
  }
1125
1291
  },
1126
1292
 
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
- },
1293
+ PropertyDefinition:
1294
+ shared[
1295
+ 'PropertyDefinition|TSAbstractPropertyDefinition|AccessorProperty|TSAbstractAccessorProperty'
1296
+ ],
1168
1297
 
1169
1298
  RestElement: shared['RestElement|SpreadElement'],
1170
1299
 
@@ -1369,6 +1498,18 @@ export default (options = {}) => {
1369
1498
  }
1370
1499
  },
1371
1500
 
1501
+ TSAbstractMethodDefinition: shared['MethodDefinition|TSAbstractMethodDefinition'],
1502
+
1503
+ TSAbstractAccessorProperty:
1504
+ shared[
1505
+ 'PropertyDefinition|TSAbstractPropertyDefinition|AccessorProperty|TSAbstractAccessorProperty'
1506
+ ],
1507
+
1508
+ TSAbstractPropertyDefinition:
1509
+ shared[
1510
+ 'PropertyDefinition|TSAbstractPropertyDefinition|AccessorProperty|TSAbstractAccessorProperty'
1511
+ ],
1512
+
1372
1513
  TSDeclareFunction(node, context) {
1373
1514
  context.write('declare ');
1374
1515
 
@@ -1442,6 +1583,18 @@ export default (options = {}) => {
1442
1583
  context.write('undefined', node);
1443
1584
  },
1444
1585
 
1586
+ TSObjectKeyword(node, context) {
1587
+ context.write('object', node);
1588
+ },
1589
+
1590
+ TSBigIntKeyword(node, context) {
1591
+ context.write('bigint', node);
1592
+ },
1593
+
1594
+ TSIntrinsicKeyword(node, context) {
1595
+ context.write('intrinsic', node);
1596
+ },
1597
+
1445
1598
  TSArrayType(node, context) {
1446
1599
  context.visit(node.elementType);
1447
1600
  context.write('[]');
@@ -1472,11 +1625,70 @@ export default (options = {}) => {
1472
1625
  }
1473
1626
  },
1474
1627
 
1628
+ TSTypeOperator(node, context) {
1629
+ context.write(node.operator + ' ');
1630
+ if (node.typeAnnotation) {
1631
+ context.visit(node.typeAnnotation);
1632
+ }
1633
+ },
1634
+
1635
+ TSTemplateLiteralType(node, context) {
1636
+ context.write('`');
1637
+ const { quasis, types } = node;
1638
+ for (let i = 0; i < types.length; i++) {
1639
+ const raw = quasis[i].value.raw;
1640
+
1641
+ context.write(raw + '${');
1642
+ context.visit(types[i]);
1643
+ context.write('}');
1644
+
1645
+ if (/\n/.test(raw)) context.multiline = true;
1646
+ }
1647
+ context.write('`');
1648
+ },
1649
+
1650
+ TSParameterProperty(node, context) {
1651
+ if (node.accessibility) {
1652
+ context.write(node.accessibility + ' ');
1653
+ }
1654
+
1655
+ if (node.readonly) {
1656
+ context.write('readonly ');
1657
+ }
1658
+
1659
+ context.visit(node.parameter);
1660
+ },
1661
+
1662
+ TSExportAssignment(node, context) {
1663
+ context.write('export = ');
1664
+ context.visit(node.expression);
1665
+ context.write(';');
1666
+ },
1667
+
1668
+ TSNamespaceExportDeclaration(node, context) {
1669
+ context.write('export as namespace ');
1670
+ context.visit(node.id);
1671
+ context.write(';');
1672
+ },
1673
+
1475
1674
  //@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
1675
  TSExpressionWithTypeArguments(node, context) {
1477
1676
  context.visit(node.expression);
1478
1677
  },
1479
1678
 
1679
+ TSTypeAssertion(node, context) {
1680
+ context.write('<');
1681
+ context.visit(node.typeAnnotation);
1682
+ context.write('>');
1683
+ if (EXPRESSIONS_PRECEDENCE[node.expression.type] < EXPRESSIONS_PRECEDENCE.TSTypeAssertion) {
1684
+ context.write('(');
1685
+ context.visit(node.expression);
1686
+ context.write(')');
1687
+ } else {
1688
+ context.visit(node.expression);
1689
+ }
1690
+ },
1691
+
1480
1692
  TSTypeParameterInstantiation(node, context) {
1481
1693
  context.write('<');
1482
1694
  for (let i = 0; i < node.params.length; i++) {
@@ -1496,8 +1708,9 @@ export default (options = {}) => {
1496
1708
  },
1497
1709
 
1498
1710
  TSTypeParameter(node, context) {
1711
+ if (node.name && node.name.type) context.visit(node.name);
1499
1712
  // @ts-expect-error type mismatch TSESTree and acorn-typescript?
1500
- context.write(node.name, node);
1713
+ else context.write(node.name, node);
1501
1714
 
1502
1715
  if (node.constraint) {
1503
1716
  context.write(' extends ');
@@ -1505,11 +1718,35 @@ export default (options = {}) => {
1505
1718
  }
1506
1719
  },
1507
1720
 
1721
+ TSTypePredicate(node, context) {
1722
+ if (node.parameterName) {
1723
+ context.visit(node.parameterName);
1724
+ } else if (node.typeAnnotation) {
1725
+ context.visit(node.typeAnnotation);
1726
+ }
1727
+
1728
+ if (node.asserts) {
1729
+ context.write(' asserts ');
1730
+ } else {
1731
+ context.write(' is ');
1732
+ }
1733
+
1734
+ if (node.typeAnnotation) {
1735
+ context.visit(node.typeAnnotation.typeAnnotation);
1736
+ }
1737
+ },
1738
+
1508
1739
  TSTypeQuery(node, context) {
1509
1740
  context.write('typeof ');
1510
1741
  context.visit(node.exprName);
1511
1742
  },
1512
1743
 
1744
+ TSClassImplements(node, context) {
1745
+ if (node.expression) {
1746
+ context.visit(node.expression);
1747
+ }
1748
+ },
1749
+
1513
1750
  TSEnumMember(node, context) {
1514
1751
  context.visit(node.id);
1515
1752
  if (node.initializer) {
@@ -1518,25 +1755,7 @@ export default (options = {}) => {
1518
1755
  }
1519
1756
  },
1520
1757
 
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
- },
1758
+ TSFunctionType: shared['TSFunctionType|TSConstructorType'],
1540
1759
 
1541
1760
  TSIndexSignature(node, context) {
1542
1761
  context.write('[');
@@ -1549,17 +1768,45 @@ export default (options = {}) => {
1549
1768
  context.visit(node.typeAnnotation);
1550
1769
  },
1551
1770
 
1771
+ TSMappedType(node, context) {
1772
+ context.write('{[');
1773
+
1774
+ if (node.typeParameter) {
1775
+ context.visit(node.typeParameter);
1776
+ } else {
1777
+ context.visit(node.key);
1778
+ context.write(' in ');
1779
+ context.visit(node.constraint);
1780
+ }
1781
+
1782
+ context.write(']');
1783
+ if (node.typeAnnotation) {
1784
+ context.write(': ');
1785
+ context.visit(node.typeAnnotation);
1786
+ }
1787
+ context.write('}');
1788
+ },
1789
+
1552
1790
  TSMethodSignature(node, context) {
1553
1791
  context.visit(node.key);
1554
1792
 
1555
1793
  context.write('(');
1556
1794
 
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);
1795
+ sequence(
1796
+ context,
1797
+ // @ts-expect-error `acorn-typescript` and `@typescript-eslint/types` have slightly different type definitions
1798
+ node.parameters ?? node.params,
1799
+ // @ts-expect-error `acorn-typescript` and `@typescript-eslint/types` have slightly different type definitions
1800
+ (node.typeAnnotation ?? node.returnType)?.loc?.start ?? null,
1801
+ false
1802
+ );
1559
1803
  context.write(')');
1560
1804
 
1561
1805
  // @ts-expect-error `acorn-typescript` and `@typescript-eslint/types` have slightly different type definitions
1562
- context.visit(node.typeAnnotation);
1806
+ if (node.typeAnnotation || node.returnType) {
1807
+ // @ts-expect-error `acorn-typescript` and `@typescript-eslint/types` have slightly different type definitions
1808
+ context.visit(node.typeAnnotation ?? node.returnType);
1809
+ }
1563
1810
  },
1564
1811
 
1565
1812
  TSTupleType(node, context) {
@@ -1582,10 +1829,18 @@ export default (options = {}) => {
1582
1829
  sequence(context, node.types, node.loc?.end ?? null, false, ' &');
1583
1830
  },
1584
1831
 
1832
+ TSInferType(node, context) {
1833
+ context.write('infer ');
1834
+ context.visit(node.typeParameter);
1835
+ },
1836
+
1585
1837
  TSLiteralType(node, context) {
1586
1838
  context.visit(node.literal);
1587
1839
  },
1588
1840
 
1841
+ TSCallSignatureDeclaration:
1842
+ shared['TSConstructSignatureDeclaration|TSCallSignatureDeclaration'],
1843
+
1589
1844
  TSConditionalType(node, context) {
1590
1845
  context.visit(node.checkType);
1591
1846
  context.write(' extends ');
@@ -1596,6 +1851,17 @@ export default (options = {}) => {
1596
1851
  context.visit(node.falseType);
1597
1852
  },
1598
1853
 
1854
+ TSConstructSignatureDeclaration:
1855
+ shared['TSConstructSignatureDeclaration|TSCallSignatureDeclaration'],
1856
+
1857
+ TSConstructorType: shared['TSFunctionType|TSConstructorType'],
1858
+
1859
+ TSExternalModuleReference(node, context) {
1860
+ context.write('require(');
1861
+ context.visit(node.expression);
1862
+ context.write(');');
1863
+ },
1864
+
1599
1865
  TSIndexedAccessType(node, context) {
1600
1866
  context.visit(node.objectType);
1601
1867
  context.write('[');
@@ -1603,6 +1869,13 @@ export default (options = {}) => {
1603
1869
  context.write(']');
1604
1870
  },
1605
1871
 
1872
+ TSImportEqualsDeclaration(node, context) {
1873
+ context.write('import ');
1874
+ context.visit(node.id);
1875
+ context.write(' = ');
1876
+ context.visit(node.moduleReference);
1877
+ },
1878
+
1606
1879
  TSImportType(node, context) {
1607
1880
  context.write('import(');
1608
1881
  context.visit(node.argument);
@@ -1614,6 +1887,20 @@ export default (options = {}) => {
1614
1887
  }
1615
1888
  },
1616
1889
 
1890
+ TSOptionalType(node, context) {
1891
+ context.visit(node.typeAnnotation);
1892
+ context.write('?');
1893
+ },
1894
+
1895
+ TSRestType(node, context) {
1896
+ context.write('...');
1897
+ context.visit(node.typeAnnotation);
1898
+ },
1899
+
1900
+ TSThisType(node, context) {
1901
+ context.write('this', node);
1902
+ },
1903
+
1617
1904
  TSAsExpression(node, context) {
1618
1905
  if (node.expression) {
1619
1906
  const needs_parens =
@@ -1637,7 +1924,7 @@ export default (options = {}) => {
1637
1924
  context.write(' {');
1638
1925
  context.indent();
1639
1926
  context.newline();
1640
- sequence(context, node.members, node.loc?.end ?? null, false);
1927
+ sequence(context, node.members ?? node.body.members, node.loc?.end ?? null, false);
1641
1928
  context.dedent();
1642
1929
  context.newline();
1643
1930
  context.write('}');
@@ -1676,7 +1963,7 @@ export default (options = {}) => {
1676
1963
  context.write('interface ');
1677
1964
  context.visit(node.id);
1678
1965
  if (node.typeParameters) context.visit(node.typeParameters);
1679
- if (node.extends) {
1966
+ if (node.extends && node.extends.length > 0) {
1680
1967
  context.write(' extends ');
1681
1968
  sequence(context, node.extends, node.body.loc?.start ?? null, false);
1682
1969
  }
@@ -1685,6 +1972,24 @@ export default (options = {}) => {
1685
1972
  context.write('}');
1686
1973
  },
1687
1974
 
1975
+ TSInstantiationExpression(node, context) {
1976
+ context.visit(node.expression);
1977
+ context.visit(node.typeArguments);
1978
+ },
1979
+
1980
+ TSInterfaceHeritage(node, context) {
1981
+ if (node.expression) {
1982
+ context.visit(node.expression);
1983
+ }
1984
+ },
1985
+
1986
+ //@ts-expect-error I don't know why, but this is relied upon in the tests, but doesn't exist in the TSESTree types
1987
+ TSParenthesizedType(node, context) {
1988
+ context.write('(');
1989
+ context.visit(node.typeAnnotation);
1990
+ context.write(')');
1991
+ },
1992
+
1688
1993
  TSSatisfiesExpression(node, context) {
1689
1994
  if (node.expression) {
1690
1995
  const needs_parens =