flow-api-translator 0.330.0 → 0.332.0

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.
@@ -503,6 +503,50 @@ const getTransforms = (originalCode, scopeManager, opts) => {
503
503
  let typeof_import_count = 0;
504
504
  return () => `$$IMPORT_TYPEOF_${++typeof_import_count}$$`;
505
505
  })();
506
+ function transformImportTypeReference(node, typeArguments = null) {
507
+ const names = [];
508
+ let current = node;
509
+ while (current.type === 'QualifiedTypeIdentifier' || current.type === 'QualifiedTypeofIdentifier') {
510
+ names.unshift(current.id);
511
+ current = current.qualification;
512
+ }
513
+ if (current.type !== 'ImportType') {
514
+ return null;
515
+ }
516
+ let qualifier = null;
517
+ for (const name of names) {
518
+ const identifier = {
519
+ type: 'Identifier',
520
+ loc: DUMMY_LOC,
521
+ name: name.name
522
+ };
523
+ qualifier = qualifier == null ? identifier : {
524
+ type: 'TSQualifiedName',
525
+ loc: DUMMY_LOC,
526
+ left: qualifier,
527
+ right: identifier
528
+ };
529
+ }
530
+ const source = {
531
+ type: 'Literal',
532
+ loc: DUMMY_LOC,
533
+ raw: current.argument.raw,
534
+ value: current.argument.value
535
+ };
536
+ return {
537
+ type: 'TSImportType',
538
+ loc: DUMMY_LOC,
539
+ argument: {
540
+ type: 'TSLiteralType',
541
+ loc: DUMMY_LOC,
542
+ literal: source
543
+ },
544
+ options: null,
545
+ qualifier,
546
+ source,
547
+ typeArguments
548
+ };
549
+ }
506
550
  const transformTypeAnnotationType = node => {
507
551
  switch (node.type) {
508
552
  case 'AnyTypeAnnotation':
@@ -555,8 +599,12 @@ const getTransforms = (originalCode, scopeManager, opts) => {
555
599
  return transform.SymbolTypeAnnotation(node);
556
600
  case 'ThisTypeAnnotation':
557
601
  return transform.ThisTypeAnnotation(node);
602
+ case 'TemplateLiteralTypeAnnotation':
603
+ return transform.TemplateLiteralTypeAnnotation(node);
558
604
  case 'TupleTypeAnnotation':
559
605
  return transform.TupleTypeAnnotation(node);
606
+ case 'TupleTypeElement':
607
+ return transform.TupleTypeElement(node);
560
608
  case 'TypeofTypeAnnotation':
561
609
  return transform.TypeofTypeAnnotation(node);
562
610
  case 'UnionTypeAnnotation':
@@ -567,6 +615,8 @@ const getTransforms = (originalCode, scopeManager, opts) => {
567
615
  return transform.TypePredicateAnnotation(node);
568
616
  case 'ConditionalTypeAnnotation':
569
617
  return transform.ConditionalTypeAnnotation(node);
618
+ case 'ConstructorTypeAnnotation':
619
+ return transform.ConstructorTypeAnnotation(node);
570
620
  case 'InferTypeAnnotation':
571
621
  return transform.InferTypeAnnotation(node);
572
622
  case 'KeyofTypeAnnotation':
@@ -585,6 +635,53 @@ const getTransforms = (originalCode, scopeManager, opts) => {
585
635
  throw unexpectedTranslationError(node, `Unhandled type ${node.type}`);
586
636
  }
587
637
  };
638
+ const declareTypeAsVariable = (specifier, type) => [{
639
+ type: 'VariableDeclaration',
640
+ loc: DUMMY_LOC,
641
+ declarations: [{
642
+ type: 'VariableDeclarator',
643
+ loc: DUMMY_LOC,
644
+ id: {
645
+ type: 'Identifier',
646
+ loc: DUMMY_LOC,
647
+ name: specifier,
648
+ typeAnnotation: {
649
+ type: 'TSTypeAnnotation',
650
+ loc: DUMMY_LOC,
651
+ typeAnnotation: transformTypeAnnotationType(type)
652
+ }
653
+ },
654
+ init: null
655
+ }],
656
+ declare: true,
657
+ kind: 'const'
658
+ }, {
659
+ type: 'TSTypeAliasDeclaration',
660
+ declare: true,
661
+ id: {
662
+ type: 'Identifier',
663
+ decorators: [],
664
+ name: specifier,
665
+ optional: false,
666
+ loc: DUMMY_LOC
667
+ },
668
+ typeAnnotation: {
669
+ type: 'TSTypeQuery',
670
+ exprName: {
671
+ type: 'Identifier',
672
+ decorators: [],
673
+ name: specifier,
674
+ optional: false,
675
+ loc: DUMMY_LOC
676
+ },
677
+ loc: DUMMY_LOC
678
+ },
679
+ loc: DUMMY_LOC
680
+ }];
681
+ const isDeclaredClass = name => {
682
+ const exportedVar = topScope.set.get(name);
683
+ return exportedVar != null && exportedVar.defs.length === 1 && exportedVar.defs[0].type === 'ClassName';
684
+ };
588
685
  const wellKnownSymbols = new Set(['iterator', 'asyncIterator', 'dispose', 'asyncDispose']);
589
686
  const transform = {
590
687
  AnyTypeAnnotation(_node) {
@@ -804,6 +901,18 @@ const getTransforms = (originalCode, scopeManager, opts) => {
804
901
  }
805
902
  }
806
903
  const superClass = node.extends.length > 0 ? node.extends[0] : undefined;
904
+ let superClassExpression = null;
905
+ let superTypeArguments;
906
+ if (superClass != null) {
907
+ switch (superClass.type) {
908
+ case 'DeclareClassExtendsCall':
909
+ return unsupportedDeclaration(superClass, 'mixin class extends clauses', node.id, true, node.typeParameters);
910
+ case 'InterfaceExtends':
911
+ superClassExpression = superClass.id.type === 'QualifiedTypeIdentifier' ? transform.QualifiedTypeIdentifier(superClass.id) : transform.Identifier(superClass.id, false);
912
+ superTypeArguments = transform.TypeParameterInstantiation(superClass.typeParameters);
913
+ break;
914
+ }
915
+ }
807
916
  return {
808
917
  type: 'ClassDeclaration',
809
918
  loc: DUMMY_LOC,
@@ -815,8 +924,8 @@ const getTransforms = (originalCode, scopeManager, opts) => {
815
924
  declare: true,
816
925
  id: transform.Identifier(node.id, false),
817
926
  implements: node.implements == null ? undefined : node.implements.map(transform.ClassImplements),
818
- superClass: superClass == null ? null : superClass.id.type === 'QualifiedTypeIdentifier' ? transform.QualifiedTypeIdentifier(superClass.id) : transform.Identifier(superClass.id, false),
819
- superTypeArguments: transform.TypeParameterInstantiation(superClass == null ? void 0 : superClass.typeParameters),
927
+ superClass: superClassExpression,
928
+ superTypeArguments,
820
929
  typeParameters: node.typeParameters == null ? undefined : transform.TypeParameterDeclaration(node.typeParameters)
821
930
  };
822
931
  },
@@ -842,6 +951,14 @@ const getTransforms = (originalCode, scopeManager, opts) => {
842
951
  case 'DeclareFunction':
843
952
  {
844
953
  const functionDecl = transform.DeclareFunction(declaration);
954
+ if (declaration.id == null) {
955
+ return {
956
+ type: 'ExportDefaultDeclaration',
957
+ loc: DUMMY_LOC,
958
+ declaration: functionDecl,
959
+ exportKind: 'value'
960
+ };
961
+ }
845
962
  const name = declaration.id.name;
846
963
  return [functionDecl, {
847
964
  type: 'ExportDefaultDeclaration',
@@ -926,77 +1043,25 @@ const getTransforms = (originalCode, scopeManager, opts) => {
926
1043
  }
927
1044
  case 'TypeofTypeAnnotation':
928
1045
  {
929
- if (declaration.type === 'TypeofTypeAnnotation' && declaration.argument.type === 'Identifier') {
930
- const name = declaration.argument.name;
931
- const exportedVar = topScope.set.get(name);
932
- if (exportedVar != null && exportedVar.defs.length === 1) {
933
- const def = exportedVar.defs[0];
934
- switch (def.type) {
935
- case 'ClassName':
936
- {
937
- return {
938
- type: 'ExportDefaultDeclaration',
939
- declaration: {
940
- type: 'Identifier',
941
- decorators: [],
942
- name,
943
- optional: false,
944
- loc: DUMMY_LOC
945
- },
946
- exportKind: 'value',
947
- loc: DUMMY_LOC
948
- };
949
- }
950
- }
951
- }
952
- }
953
- }
954
- default:
955
- {
956
- const SPECIFIER = '$$EXPORT_DEFAULT_DECLARATION$$';
957
- return [{
958
- type: 'VariableDeclaration',
959
- loc: DUMMY_LOC,
960
- declarations: [{
961
- type: 'VariableDeclarator',
962
- loc: DUMMY_LOC,
963
- id: {
964
- type: 'Identifier',
965
- loc: DUMMY_LOC,
966
- name: SPECIFIER,
967
- typeAnnotation: {
968
- type: 'TSTypeAnnotation',
969
- loc: DUMMY_LOC,
970
- typeAnnotation: transformTypeAnnotationType(declaration)
971
- }
972
- },
973
- init: null
974
- }],
975
- declare: true,
976
- kind: 'const'
977
- }, {
978
- type: 'TSTypeAliasDeclaration',
979
- declare: true,
980
- id: {
981
- type: 'Identifier',
982
- decorators: [],
983
- name: SPECIFIER,
984
- optional: false,
985
- loc: DUMMY_LOC
986
- },
987
- typeAnnotation: {
988
- type: 'TSTypeQuery',
989
- exprName: {
1046
+ if (declaration.type === 'TypeofTypeAnnotation' && declaration.argument.type === 'Identifier' && isDeclaredClass(declaration.argument.name)) {
1047
+ return {
1048
+ type: 'ExportDefaultDeclaration',
1049
+ declaration: {
990
1050
  type: 'Identifier',
991
1051
  decorators: [],
992
- name: SPECIFIER,
1052
+ name: declaration.argument.name,
993
1053
  optional: false,
994
1054
  loc: DUMMY_LOC
995
1055
  },
1056
+ exportKind: 'value',
996
1057
  loc: DUMMY_LOC
997
- },
998
- loc: DUMMY_LOC
999
- }, {
1058
+ };
1059
+ }
1060
+ }
1061
+ default:
1062
+ {
1063
+ const SPECIFIER = (0, _TSNodeUtils.getDefaultExportBindingName)(declaration, opts.useSemanticDefaultExportNames === true);
1064
+ return [...declareTypeAsVariable(SPECIFIER, declaration), {
1000
1065
  type: 'ExportDefaultDeclaration',
1001
1066
  loc: DUMMY_LOC,
1002
1067
  declaration: {
@@ -1048,6 +1113,11 @@ const getTransforms = (originalCode, scopeManager, opts) => {
1048
1113
  declaration: transform.DeclareInterface(node.declaration),
1049
1114
  exportKind: 'type'
1050
1115
  }];
1116
+ case 'DeclareNamespace':
1117
+ return [{
1118
+ declaration: unsupportedDeclaration(node.declaration, 'namespaces', node.declaration.id),
1119
+ exportKind: 'value'
1120
+ }];
1051
1121
  case 'DeclareOpaqueType':
1052
1122
  return [{
1053
1123
  declaration: transform.DeclareOpaqueType(node.declaration),
@@ -1279,8 +1349,13 @@ const getTransforms = (originalCode, scopeManager, opts) => {
1279
1349
  };
1280
1350
  },
1281
1351
  DeclareFunction(node) {
1282
- const id = transform.Identifier(node.id, false);
1283
- const functionInfo = transform.FunctionTypeAnnotation(node.id.typeAnnotation.typeAnnotation);
1352
+ var _node$id$typeAnnotati, _node$id;
1353
+ const annotation = (_node$id$typeAnnotati = (_node$id = node.id) == null ? void 0 : _node$id.typeAnnotation) != null ? _node$id$typeAnnotati : node.typeAnnotation;
1354
+ if (annotation == null) {
1355
+ throw translationError(node, 'Declare function is missing its type');
1356
+ }
1357
+ const functionType = annotation.typeAnnotation;
1358
+ const functionInfo = transform.FunctionTypeAnnotation(functionType);
1284
1359
  return {
1285
1360
  type: 'TSDeclareFunction',
1286
1361
  loc: DUMMY_LOC,
@@ -1289,10 +1364,10 @@ const getTransforms = (originalCode, scopeManager, opts) => {
1289
1364
  declare: true,
1290
1365
  expression: false,
1291
1366
  generator: false,
1292
- id: {
1367
+ id: node.id == null ? null : {
1293
1368
  type: 'Identifier',
1294
1369
  loc: DUMMY_LOC,
1295
- name: id.name
1370
+ name: node.id.name
1296
1371
  },
1297
1372
  params: functionInfo.params,
1298
1373
  returnType: functionInfo.returnType,
@@ -1409,7 +1484,31 @@ const getTransforms = (originalCode, scopeManager, opts) => {
1409
1484
  return EnumImpl(node);
1410
1485
  },
1411
1486
  DeclareModuleExports(node) {
1412
- throw translationError(node, 'CommonJS exports are not supported.');
1487
+ if (node.parent.type === 'Program' && node.parent.body.some(statement => statement.type === 'DeclareExportAllDeclaration' || statement.type === 'DeclareExportDeclaration' || statement.type === 'ExportAllDeclaration' || statement.type === 'ExportDefaultDeclaration' || statement.type === 'ExportNamedDeclaration')) {
1488
+ throw translationError(node, 'CommonJS exports cannot be combined with ES module exports.');
1489
+ }
1490
+ const type = node.typeAnnotation.typeAnnotation;
1491
+ if (type.type === 'TypeofTypeAnnotation' && type.argument.type === 'Identifier' && isDeclaredClass(type.argument.name)) {
1492
+ return {
1493
+ type: 'TSExportAssignment',
1494
+ loc: DUMMY_LOC,
1495
+ expression: {
1496
+ type: 'Identifier',
1497
+ loc: DUMMY_LOC,
1498
+ name: type.argument.name
1499
+ }
1500
+ };
1501
+ }
1502
+ const SPECIFIER = '$$MODULE_EXPORTS$$';
1503
+ return [...declareTypeAsVariable(SPECIFIER, type), {
1504
+ type: 'TSExportAssignment',
1505
+ loc: DUMMY_LOC,
1506
+ expression: {
1507
+ type: 'Identifier',
1508
+ loc: DUMMY_LOC,
1509
+ name: SPECIFIER
1510
+ }
1511
+ }];
1413
1512
  },
1414
1513
  ExistsTypeAnnotation(node) {
1415
1514
  return unsupportedAnnotation(node, 'existential type');
@@ -1489,7 +1588,39 @@ const getTransforms = (originalCode, scopeManager, opts) => {
1489
1588
  loc: DUMMY_LOC,
1490
1589
  exported: transform.Identifier(node.exported, false),
1491
1590
  local: transform.Identifier(node.local, false),
1492
- exportKind: 'value'
1591
+ exportKind: node.exportKind
1592
+ };
1593
+ },
1594
+ ConstructorTypeAnnotation(node) {
1595
+ const params = node.params.map(transform.FunctionTypeParam);
1596
+ if (node.rest != null) {
1597
+ const rest = node.rest;
1598
+ params.push({
1599
+ type: 'RestElement',
1600
+ loc: DUMMY_LOC,
1601
+ argument: rest.name == null ? {
1602
+ type: 'Identifier',
1603
+ loc: DUMMY_LOC,
1604
+ name: '$$REST$$'
1605
+ } : transform.Identifier(rest.name, false),
1606
+ typeAnnotation: {
1607
+ type: 'TSTypeAnnotation',
1608
+ loc: DUMMY_LOC,
1609
+ typeAnnotation: transformTypeAnnotationType(rest.typeAnnotation)
1610
+ }
1611
+ });
1612
+ }
1613
+ return {
1614
+ type: 'TSConstructorType',
1615
+ loc: DUMMY_LOC,
1616
+ abstract: node.abstract,
1617
+ params,
1618
+ returnType: {
1619
+ type: 'TSTypeAnnotation',
1620
+ loc: DUMMY_LOC,
1621
+ typeAnnotation: transformTypeAnnotationType(node.returnType)
1622
+ },
1623
+ typeParameters: node.typeParameters == null ? undefined : transform.TypeParameterDeclaration(node.typeParameters)
1493
1624
  };
1494
1625
  },
1495
1626
  FunctionTypeAnnotation(node) {
@@ -1530,7 +1661,10 @@ const getTransforms = (originalCode, scopeManager, opts) => {
1530
1661
  returnType: {
1531
1662
  type: 'TSTypeAnnotation',
1532
1663
  loc: DUMMY_LOC,
1533
- typeAnnotation: transformTypeAnnotationType(node.returnType)
1664
+ typeAnnotation: node.returnType == null ? {
1665
+ type: 'TSAnyKeyword',
1666
+ loc: DUMMY_LOC
1667
+ } : transformTypeAnnotationType(node.returnType)
1534
1668
  },
1535
1669
  typeParameters: node.typeParameters == null ? undefined : transform.TypeParameterDeclaration(node.typeParameters)
1536
1670
  };
@@ -1549,6 +1683,11 @@ const getTransforms = (originalCode, scopeManager, opts) => {
1549
1683
  };
1550
1684
  },
1551
1685
  GenericTypeAnnotation(node) {
1686
+ var _transform$TypeParame;
1687
+ const importType = transformImportTypeReference(node.id, (_transform$TypeParame = transform.TypeParameterInstantiation(node.typeParameters)) != null ? _transform$TypeParame : null);
1688
+ if (importType != null) {
1689
+ return importType;
1690
+ }
1552
1691
  const [fullTypeName, baseId] = (() => {
1553
1692
  let names = [];
1554
1693
  let currentNode = node.id;
@@ -2410,10 +2549,14 @@ const getTransforms = (originalCode, scopeManager, opts) => {
2410
2549
  return unsupportedAnnotation(node, fullTypeName);
2411
2550
  }
2412
2551
  }
2552
+ const typeName = node.id.type === 'Identifier' ? transform.Identifier(node.id, false) : node.id.type === 'QualifiedTypeIdentifier' ? transform.QualifiedTypeIdentifier(node.id) : null;
2553
+ if (typeName == null) {
2554
+ throw unexpectedTranslationError(node, 'Unreachable import type');
2555
+ }
2413
2556
  return {
2414
2557
  type: 'TSTypeReference',
2415
2558
  loc: DUMMY_LOC,
2416
- typeName: node.id.type === 'Identifier' ? transform.Identifier(node.id, false) : transform.QualifiedTypeIdentifier(node.id),
2559
+ typeName,
2417
2560
  typeArguments: transform.TypeParameterInstantiation(node.typeParameters)
2418
2561
  };
2419
2562
  },
@@ -2615,7 +2758,7 @@ const getTransforms = (originalCode, scopeManager, opts) => {
2615
2758
  },
2616
2759
  ObjectTypeAnnotation(node) {
2617
2760
  if (node.properties.length === 1 && node.properties[0].type === 'ObjectTypeMappedTypeProperty') {
2618
- var _prop$variance, _prop$variance2;
2761
+ var _prop$varianceOp, _prop$variance, _prop$variance2;
2619
2762
  const prop = node.properties[0];
2620
2763
  const tsProp = {
2621
2764
  type: 'TSMappedType',
@@ -2638,10 +2781,10 @@ const getTransforms = (originalCode, scopeManager, opts) => {
2638
2781
  name: prop.keyTparam.name
2639
2782
  },
2640
2783
  constraint: transformTypeAnnotationType(prop.sourceType),
2641
- readonly: ((_prop$variance = prop.variance) == null ? void 0 : _prop$variance.kind) === 'plus' || ((_prop$variance2 = prop.variance) == null ? void 0 : _prop$variance2.kind) === 'readonly',
2784
+ readonly: (_prop$varianceOp = prop.varianceOp) != null ? _prop$varianceOp : ((_prop$variance = prop.variance) == null ? void 0 : _prop$variance.kind) === 'plus' || ((_prop$variance2 = prop.variance) == null ? void 0 : _prop$variance2.kind) === 'readonly',
2642
2785
  optional: prop.optional === 'Optional',
2643
2786
  typeAnnotation: transformTypeAnnotationType(prop.propType),
2644
- nameType: null
2787
+ nameType: prop.nameType == null ? null : transformTypeAnnotationType(prop.nameType)
2645
2788
  };
2646
2789
  return tsProp;
2647
2790
  }
@@ -2669,6 +2812,9 @@ const getTransforms = (originalCode, scopeManager, opts) => {
2669
2812
  if (property.type === 'ObjectTypeMappedTypeProperty') {
2670
2813
  return unsupportedAnnotation(property, 'object type with mapped type property along with other properties');
2671
2814
  }
2815
+ if (property.type === 'ObjectTypePrivateField') {
2816
+ return unsupportedAnnotation(property, 'private type fields');
2817
+ }
2672
2818
  members.push({
2673
2819
  start: property.range[0],
2674
2820
  node: transform.ObjectTypeProperty(property)
@@ -2700,6 +2846,8 @@ const getTransforms = (originalCode, scopeManager, opts) => {
2700
2846
  typesToIntersect.push(spreadType);
2701
2847
  } else if (property.type === 'ObjectTypeMappedTypeProperty') {
2702
2848
  return unsupportedAnnotation(property, 'object type with mapped type property');
2849
+ } else if (property.type === 'ObjectTypePrivateField') {
2850
+ return unsupportedAnnotation(property, 'private type fields');
2703
2851
  } else {
2704
2852
  members.push({
2705
2853
  start: property.range[0],
@@ -2772,6 +2920,9 @@ const getTransforms = (originalCode, scopeManager, opts) => {
2772
2920
  var _node$variance3, _node$variance4;
2773
2921
  if (node.key.type === 'GenericTypeAnnotation') {
2774
2922
  var _node$variance, _node$variance2;
2923
+ if (node.key.id.type === 'ImportType') {
2924
+ throw translationError(node, 'Unsupported import type indexer key');
2925
+ }
2775
2926
  const ident = node.key.id.type === 'Identifier' ? node.key.id : node.key.id.id;
2776
2927
  return {
2777
2928
  type: 'TSPropertySignature',
@@ -2929,19 +3080,27 @@ const getTransforms = (originalCode, scopeManager, opts) => {
2929
3080
  },
2930
3081
  QualifiedTypeIdentifier(node) {
2931
3082
  const qual = node.qualification;
3083
+ if (qual.type === 'ImportType') {
3084
+ throw unexpectedTranslationError(qual, 'Unreachable import type');
3085
+ }
3086
+ const left = qual.type === 'Identifier' ? transform.Identifier(qual, false) : transform.QualifiedTypeIdentifier(qual);
2932
3087
  return {
2933
3088
  type: 'TSQualifiedName',
2934
3089
  loc: DUMMY_LOC,
2935
- left: qual.type === 'Identifier' ? transform.Identifier(qual, false) : transform.QualifiedTypeIdentifier(qual),
3090
+ left,
2936
3091
  right: transform.Identifier(node.id, false)
2937
3092
  };
2938
3093
  },
2939
3094
  QualifiedTypeofIdentifier(node) {
2940
3095
  const qual = node.qualification;
3096
+ if (qual.type === 'ImportType') {
3097
+ throw unexpectedTranslationError(qual, 'Unreachable import type');
3098
+ }
3099
+ const left = qual.type === 'Identifier' ? transform.Identifier(qual, false) : transform.QualifiedTypeofIdentifier(qual);
2941
3100
  return {
2942
3101
  type: 'TSQualifiedName',
2943
3102
  loc: DUMMY_LOC,
2944
- left: qual.type === 'Identifier' ? transform.Identifier(qual, false) : transform.QualifiedTypeofIdentifier(qual),
3103
+ left,
2945
3104
  right: transform.Identifier(node.id, false)
2946
3105
  };
2947
3106
  },
@@ -2995,6 +3154,22 @@ const getTransforms = (originalCode, scopeManager, opts) => {
2995
3154
  loc: DUMMY_LOC
2996
3155
  };
2997
3156
  },
3157
+ TemplateLiteralTypeAnnotation(node) {
3158
+ return {
3159
+ type: 'TSTemplateLiteralType',
3160
+ loc: DUMMY_LOC,
3161
+ quasis: node.quasis.map(quasi => ({
3162
+ type: 'TemplateElement',
3163
+ loc: DUMMY_LOC,
3164
+ tail: quasi.tail,
3165
+ value: {
3166
+ cooked: quasi.value.cooked,
3167
+ raw: quasi.value.raw
3168
+ }
3169
+ })),
3170
+ types: node.types.map(transformTypeAnnotationType)
3171
+ };
3172
+ },
2998
3173
  TupleTypeAnnotation(node) {
2999
3174
  const allReadOnly = node.elementTypes.length > 0 && node.elementTypes.every(element => element.type === 'TupleTypeLabeledElement' && element.variance != null && (element.variance.kind === 'plus' || element.variance.kind === 'readonly'));
3000
3175
  const elems = node.elementTypes.map(element => {
@@ -3053,6 +3228,14 @@ const getTransforms = (originalCode, scopeManager, opts) => {
3053
3228
  typeAnnotation: tupleAnnot
3054
3229
  } : tupleAnnot;
3055
3230
  },
3231
+ TupleTypeElement(node) {
3232
+ const elementType = transformTypeAnnotationType(node.elementType);
3233
+ return node.optional ? {
3234
+ type: 'TSOptionalType',
3235
+ loc: DUMMY_LOC,
3236
+ typeAnnotation: elementType
3237
+ } : elementType;
3238
+ },
3056
3239
  TypeAlias(node) {
3057
3240
  return transform.DeclareTypeAlias(node);
3058
3241
  },
@@ -3064,6 +3247,27 @@ const getTransforms = (originalCode, scopeManager, opts) => {
3064
3247
  };
3065
3248
  },
3066
3249
  TypeofTypeAnnotation(node) {
3250
+ if (node.argument.type === 'ImportType') {
3251
+ const importType = transformImportTypeReference(node.argument);
3252
+ if (importType == null) {
3253
+ throw unexpectedTranslationError(node, 'Invalid import type');
3254
+ }
3255
+ return {
3256
+ type: 'TSTypeQuery',
3257
+ loc: DUMMY_LOC,
3258
+ exprName: importType,
3259
+ typeArguments: undefined
3260
+ };
3261
+ }
3262
+ const importType = node.argument.type === 'QualifiedTypeofIdentifier' ? transformImportTypeReference(node.argument) : null;
3263
+ if (importType != null) {
3264
+ return {
3265
+ type: 'TSTypeQuery',
3266
+ loc: DUMMY_LOC,
3267
+ exprName: importType,
3268
+ typeArguments: undefined
3269
+ };
3270
+ }
3067
3271
  switch (node.argument.type) {
3068
3272
  case 'Identifier':
3069
3273
  return {
@@ -3079,6 +3283,8 @@ const getTransforms = (originalCode, scopeManager, opts) => {
3079
3283
  exprName: transform.QualifiedTypeofIdentifier(node.argument),
3080
3284
  typeArguments: undefined
3081
3285
  };
3286
+ default:
3287
+ throw unexpectedTranslationError(node.argument, 'Unexpected typeof annotation argument');
3082
3288
  }
3083
3289
  },
3084
3290
  TypeParameter(node) {
@@ -3184,6 +3390,13 @@ const getTransforms = (originalCode, scopeManager, opts) => {
3184
3390
  },
3185
3391
  TypeOperator(node) {
3186
3392
  switch (node.operator) {
3393
+ case 'unique':
3394
+ return {
3395
+ type: 'TSTypeOperator',
3396
+ loc: DUMMY_LOC,
3397
+ operator: 'unique',
3398
+ typeAnnotation: transformTypeAnnotationType(node.typeAnnotation)
3399
+ };
3187
3400
  case 'renders':
3188
3401
  case 'renders?':
3189
3402
  case 'renders*':