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.
- package/README.md +17 -0
- package/dist/TSDefToFlowDef.js +17 -7
- package/dist/TSDefToFlowDef.js.flow +18 -2
- package/dist/flowDefToTSDef.js +293 -80
- package/dist/flowDefToTSDef.js.flow +441 -123
- package/dist/flowToFlowDef.js +121 -2
- package/dist/flowToFlowDef.js.flow +244 -2
- package/dist/index.js +7 -6
- package/dist/index.js.flow +16 -4
- package/dist/src/TSDefToFlowDef.js +17 -7
- package/dist/src/flowDefToTSDef.js +293 -80
- package/dist/src/flowToFlowDef.js +121 -2
- package/dist/src/index.js +7 -6
- package/dist/src/utils/TSNodeUtils.js +20 -0
- package/dist/utils/TSNodeUtils.js +20 -0
- package/dist/utils/TSNodeUtils.js.flow +46 -1
- package/dist/utils/TranslationUtils.js.flow +16 -0
- package/package.json +5 -5
|
@@ -29,6 +29,7 @@ import {removeAtFlowFromDocblock} from './utils/DocblockUtils';
|
|
|
29
29
|
import {
|
|
30
30
|
ensureTypeIncludesUndefined,
|
|
31
31
|
extractPropertyKeyLiterals,
|
|
32
|
+
getDefaultExportBindingName,
|
|
32
33
|
} from './utils/TSNodeUtils';
|
|
33
34
|
import {EOL} from 'os';
|
|
34
35
|
|
|
@@ -745,6 +746,66 @@ const getTransforms = (
|
|
|
745
746
|
return () => `$$IMPORT_TYPEOF_${++typeof_import_count}$$`;
|
|
746
747
|
})();
|
|
747
748
|
|
|
749
|
+
function transformImportTypeReference(
|
|
750
|
+
node:
|
|
751
|
+
| FlowESTree.ImportType
|
|
752
|
+
| FlowESTree.Identifier
|
|
753
|
+
| FlowESTree.QualifiedTypeIdentifier
|
|
754
|
+
| FlowESTree.QualifiedTypeofIdentifier,
|
|
755
|
+
typeArguments: TSESTree.TSTypeParameterInstantiation | null = null,
|
|
756
|
+
): TSESTree.TSImportType | null {
|
|
757
|
+
const names: Array<FlowESTree.Identifier> = [];
|
|
758
|
+
let current = node;
|
|
759
|
+
while (
|
|
760
|
+
current.type === 'QualifiedTypeIdentifier' ||
|
|
761
|
+
current.type === 'QualifiedTypeofIdentifier'
|
|
762
|
+
) {
|
|
763
|
+
names.unshift(current.id);
|
|
764
|
+
current = current.qualification;
|
|
765
|
+
}
|
|
766
|
+
if (current.type !== 'ImportType') {
|
|
767
|
+
return null;
|
|
768
|
+
}
|
|
769
|
+
|
|
770
|
+
let qualifier: TSESTree.EntityName | null = null;
|
|
771
|
+
for (const name of names) {
|
|
772
|
+
const identifier: TSESTree.Identifier = {
|
|
773
|
+
type: 'Identifier',
|
|
774
|
+
loc: DUMMY_LOC,
|
|
775
|
+
name: name.name,
|
|
776
|
+
};
|
|
777
|
+
qualifier =
|
|
778
|
+
qualifier == null
|
|
779
|
+
? identifier
|
|
780
|
+
: {
|
|
781
|
+
type: 'TSQualifiedName',
|
|
782
|
+
loc: DUMMY_LOC,
|
|
783
|
+
left: qualifier,
|
|
784
|
+
right: identifier,
|
|
785
|
+
};
|
|
786
|
+
}
|
|
787
|
+
|
|
788
|
+
const source: TSESTree.StringLiteral = {
|
|
789
|
+
type: 'Literal',
|
|
790
|
+
loc: DUMMY_LOC,
|
|
791
|
+
raw: current.argument.raw,
|
|
792
|
+
value: current.argument.value,
|
|
793
|
+
};
|
|
794
|
+
return {
|
|
795
|
+
type: 'TSImportType',
|
|
796
|
+
loc: DUMMY_LOC,
|
|
797
|
+
argument: {
|
|
798
|
+
type: 'TSLiteralType',
|
|
799
|
+
loc: DUMMY_LOC,
|
|
800
|
+
literal: source,
|
|
801
|
+
},
|
|
802
|
+
options: null,
|
|
803
|
+
qualifier,
|
|
804
|
+
source,
|
|
805
|
+
typeArguments,
|
|
806
|
+
};
|
|
807
|
+
}
|
|
808
|
+
|
|
748
809
|
const transformTypeAnnotationType = (
|
|
749
810
|
node: FlowESTree.TypeAnnotationType,
|
|
750
811
|
): TSESTree.TypeNode => {
|
|
@@ -799,8 +860,12 @@ const getTransforms = (
|
|
|
799
860
|
return transform.SymbolTypeAnnotation(node);
|
|
800
861
|
case 'ThisTypeAnnotation':
|
|
801
862
|
return transform.ThisTypeAnnotation(node);
|
|
863
|
+
case 'TemplateLiteralTypeAnnotation':
|
|
864
|
+
return transform.TemplateLiteralTypeAnnotation(node);
|
|
802
865
|
case 'TupleTypeAnnotation':
|
|
803
866
|
return transform.TupleTypeAnnotation(node);
|
|
867
|
+
case 'TupleTypeElement':
|
|
868
|
+
return transform.TupleTypeElement(node);
|
|
804
869
|
case 'TypeofTypeAnnotation':
|
|
805
870
|
return transform.TypeofTypeAnnotation(node);
|
|
806
871
|
case 'UnionTypeAnnotation':
|
|
@@ -811,6 +876,8 @@ const getTransforms = (
|
|
|
811
876
|
return transform.TypePredicateAnnotation(node);
|
|
812
877
|
case 'ConditionalTypeAnnotation':
|
|
813
878
|
return transform.ConditionalTypeAnnotation(node);
|
|
879
|
+
case 'ConstructorTypeAnnotation':
|
|
880
|
+
return transform.ConstructorTypeAnnotation(node);
|
|
814
881
|
case 'InferTypeAnnotation':
|
|
815
882
|
return transform.InferTypeAnnotation(node);
|
|
816
883
|
case 'KeyofTypeAnnotation':
|
|
@@ -830,6 +897,83 @@ const getTransforms = (
|
|
|
830
897
|
}
|
|
831
898
|
};
|
|
832
899
|
|
|
900
|
+
/*
|
|
901
|
+
Flow can export a bare type, eg
|
|
902
|
+
```
|
|
903
|
+
declare export default TypeName;
|
|
904
|
+
declare module.exports: TypeName;
|
|
905
|
+
```
|
|
906
|
+
but TS can only export values, so declare a temporary variable to hold the
|
|
907
|
+
type and reference that in the export declaration:
|
|
908
|
+
```
|
|
909
|
+
declare const SPECIFIER: TypeName;
|
|
910
|
+
declare type SPECIFIER = typeof SPECIFIER;
|
|
911
|
+
```
|
|
912
|
+
*/
|
|
913
|
+
const declareTypeAsVariable = (
|
|
914
|
+
specifier: string,
|
|
915
|
+
type: FlowESTree.TypeAnnotationType,
|
|
916
|
+
): [TSESTree.VariableDeclaration, TSESTree.TSTypeAliasDeclaration] => [
|
|
917
|
+
{
|
|
918
|
+
type: 'VariableDeclaration',
|
|
919
|
+
loc: DUMMY_LOC,
|
|
920
|
+
declarations: [
|
|
921
|
+
{
|
|
922
|
+
type: 'VariableDeclarator',
|
|
923
|
+
loc: DUMMY_LOC,
|
|
924
|
+
id: {
|
|
925
|
+
type: 'Identifier',
|
|
926
|
+
loc: DUMMY_LOC,
|
|
927
|
+
name: specifier,
|
|
928
|
+
typeAnnotation: {
|
|
929
|
+
type: 'TSTypeAnnotation',
|
|
930
|
+
loc: DUMMY_LOC,
|
|
931
|
+
typeAnnotation: transformTypeAnnotationType(type),
|
|
932
|
+
},
|
|
933
|
+
},
|
|
934
|
+
init: null,
|
|
935
|
+
},
|
|
936
|
+
],
|
|
937
|
+
declare: true,
|
|
938
|
+
kind: 'const',
|
|
939
|
+
},
|
|
940
|
+
{
|
|
941
|
+
type: 'TSTypeAliasDeclaration',
|
|
942
|
+
declare: true,
|
|
943
|
+
id: {
|
|
944
|
+
type: 'Identifier',
|
|
945
|
+
decorators: [],
|
|
946
|
+
name: specifier,
|
|
947
|
+
optional: false,
|
|
948
|
+
loc: DUMMY_LOC,
|
|
949
|
+
},
|
|
950
|
+
typeAnnotation: {
|
|
951
|
+
type: 'TSTypeQuery',
|
|
952
|
+
exprName: {
|
|
953
|
+
type: 'Identifier',
|
|
954
|
+
decorators: [],
|
|
955
|
+
name: specifier,
|
|
956
|
+
optional: false,
|
|
957
|
+
loc: DUMMY_LOC,
|
|
958
|
+
},
|
|
959
|
+
loc: DUMMY_LOC,
|
|
960
|
+
},
|
|
961
|
+
loc: DUMMY_LOC,
|
|
962
|
+
},
|
|
963
|
+
];
|
|
964
|
+
|
|
965
|
+
// Whether `name` is bound at the top level by a class declaration, which is
|
|
966
|
+
// the one case where `typeof name` can be re-exported as `name` itself and
|
|
967
|
+
// keep both its value and its type meaning.
|
|
968
|
+
const isDeclaredClass = (name: string): boolean => {
|
|
969
|
+
const exportedVar = topScope.set.get(name);
|
|
970
|
+
return (
|
|
971
|
+
exportedVar != null &&
|
|
972
|
+
exportedVar.defs.length === 1 &&
|
|
973
|
+
exportedVar.defs[0].type === 'ClassName'
|
|
974
|
+
);
|
|
975
|
+
};
|
|
976
|
+
|
|
833
977
|
const wellKnownSymbols = new Set([
|
|
834
978
|
'iterator',
|
|
835
979
|
'asyncIterator',
|
|
@@ -1127,6 +1271,29 @@ const getTransforms = (
|
|
|
1127
1271
|
}
|
|
1128
1272
|
|
|
1129
1273
|
const superClass = node.extends.length > 0 ? node.extends[0] : undefined;
|
|
1274
|
+
let superClassExpression: TSESTree.LeftHandSideExpression | null = null;
|
|
1275
|
+
let superTypeArguments: TSESTree.TSTypeParameterInstantiation | void;
|
|
1276
|
+
if (superClass != null) {
|
|
1277
|
+
switch (superClass.type) {
|
|
1278
|
+
case 'DeclareClassExtendsCall':
|
|
1279
|
+
return unsupportedDeclaration(
|
|
1280
|
+
superClass,
|
|
1281
|
+
'mixin class extends clauses',
|
|
1282
|
+
node.id,
|
|
1283
|
+
true,
|
|
1284
|
+
node.typeParameters,
|
|
1285
|
+
);
|
|
1286
|
+
case 'InterfaceExtends':
|
|
1287
|
+
superClassExpression =
|
|
1288
|
+
superClass.id.type === 'QualifiedTypeIdentifier'
|
|
1289
|
+
? transform.QualifiedTypeIdentifier(superClass.id)
|
|
1290
|
+
: transform.Identifier(superClass.id as $FlowFixMe, false);
|
|
1291
|
+
superTypeArguments = transform.TypeParameterInstantiation(
|
|
1292
|
+
superClass.typeParameters,
|
|
1293
|
+
);
|
|
1294
|
+
break;
|
|
1295
|
+
}
|
|
1296
|
+
}
|
|
1130
1297
|
|
|
1131
1298
|
return {
|
|
1132
1299
|
type: 'ClassDeclaration',
|
|
@@ -1142,15 +1309,8 @@ const getTransforms = (
|
|
|
1142
1309
|
node.implements == null
|
|
1143
1310
|
? undefined
|
|
1144
1311
|
: node.implements.map(transform.ClassImplements),
|
|
1145
|
-
superClass:
|
|
1146
|
-
|
|
1147
|
-
? null
|
|
1148
|
-
: superClass.id.type === 'QualifiedTypeIdentifier'
|
|
1149
|
-
? transform.QualifiedTypeIdentifier(superClass.id)
|
|
1150
|
-
: transform.Identifier(superClass.id as $FlowFixMe, false),
|
|
1151
|
-
superTypeArguments: transform.TypeParameterInstantiation(
|
|
1152
|
-
superClass?.typeParameters,
|
|
1153
|
-
),
|
|
1312
|
+
superClass: superClassExpression,
|
|
1313
|
+
superTypeArguments,
|
|
1154
1314
|
typeParameters:
|
|
1155
1315
|
node.typeParameters == null
|
|
1156
1316
|
? undefined
|
|
@@ -1209,6 +1369,14 @@ const getTransforms = (
|
|
|
1209
1369
|
// TS doesn't support direct default export for declare'd functions
|
|
1210
1370
|
case 'DeclareFunction': {
|
|
1211
1371
|
const functionDecl = transform.DeclareFunction(declaration);
|
|
1372
|
+
if (declaration.id == null) {
|
|
1373
|
+
return {
|
|
1374
|
+
type: 'ExportDefaultDeclaration',
|
|
1375
|
+
loc: DUMMY_LOC,
|
|
1376
|
+
declaration: functionDecl,
|
|
1377
|
+
exportKind: 'value',
|
|
1378
|
+
};
|
|
1379
|
+
}
|
|
1212
1380
|
const name = declaration.id.name;
|
|
1213
1381
|
return [
|
|
1214
1382
|
functionDecl,
|
|
@@ -1332,97 +1500,33 @@ const getTransforms = (
|
|
|
1332
1500
|
case 'TypeofTypeAnnotation': {
|
|
1333
1501
|
if (
|
|
1334
1502
|
declaration.type === 'TypeofTypeAnnotation' &&
|
|
1335
|
-
declaration.argument.type === 'Identifier'
|
|
1503
|
+
declaration.argument.type === 'Identifier' &&
|
|
1504
|
+
isDeclaredClass(declaration.argument.name)
|
|
1336
1505
|
) {
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
name,
|
|
1350
|
-
optional: false,
|
|
1351
|
-
loc: DUMMY_LOC,
|
|
1352
|
-
},
|
|
1353
|
-
exportKind: 'value',
|
|
1354
|
-
loc: DUMMY_LOC,
|
|
1355
|
-
};
|
|
1356
|
-
}
|
|
1357
|
-
}
|
|
1358
|
-
}
|
|
1506
|
+
return {
|
|
1507
|
+
type: 'ExportDefaultDeclaration',
|
|
1508
|
+
declaration: {
|
|
1509
|
+
type: 'Identifier',
|
|
1510
|
+
decorators: [],
|
|
1511
|
+
name: declaration.argument.name,
|
|
1512
|
+
optional: false,
|
|
1513
|
+
loc: DUMMY_LOC,
|
|
1514
|
+
},
|
|
1515
|
+
exportKind: 'value',
|
|
1516
|
+
loc: DUMMY_LOC,
|
|
1517
|
+
};
|
|
1359
1518
|
}
|
|
1360
1519
|
|
|
1361
1520
|
// intentional fallthrough to the "default" handling
|
|
1362
1521
|
}
|
|
1363
1522
|
|
|
1364
1523
|
default: {
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
```
|
|
1370
|
-
but TS does not, so we have to declare a temporary variable to
|
|
1371
|
-
reference in the export declaration:
|
|
1372
|
-
```
|
|
1373
|
-
declare const $$EXPORT_DEFAULT_DECLARATION$$: TypeName;
|
|
1374
|
-
export default $$EXPORT_DEFAULT_DECLARATION$$;
|
|
1375
|
-
```
|
|
1376
|
-
*/
|
|
1377
|
-
const SPECIFIER = '$$EXPORT_DEFAULT_DECLARATION$$';
|
|
1524
|
+
const SPECIFIER = getDefaultExportBindingName(
|
|
1525
|
+
declaration,
|
|
1526
|
+
opts.useSemanticDefaultExportNames === true,
|
|
1527
|
+
);
|
|
1378
1528
|
return [
|
|
1379
|
-
|
|
1380
|
-
type: 'VariableDeclaration',
|
|
1381
|
-
loc: DUMMY_LOC,
|
|
1382
|
-
declarations: [
|
|
1383
|
-
{
|
|
1384
|
-
type: 'VariableDeclarator',
|
|
1385
|
-
loc: DUMMY_LOC,
|
|
1386
|
-
id: {
|
|
1387
|
-
type: 'Identifier',
|
|
1388
|
-
loc: DUMMY_LOC,
|
|
1389
|
-
name: SPECIFIER,
|
|
1390
|
-
typeAnnotation: {
|
|
1391
|
-
type: 'TSTypeAnnotation',
|
|
1392
|
-
loc: DUMMY_LOC,
|
|
1393
|
-
typeAnnotation:
|
|
1394
|
-
transformTypeAnnotationType(declaration),
|
|
1395
|
-
},
|
|
1396
|
-
},
|
|
1397
|
-
init: null,
|
|
1398
|
-
},
|
|
1399
|
-
],
|
|
1400
|
-
declare: true,
|
|
1401
|
-
kind: 'const',
|
|
1402
|
-
},
|
|
1403
|
-
{
|
|
1404
|
-
type: 'TSTypeAliasDeclaration',
|
|
1405
|
-
declare: true,
|
|
1406
|
-
id: {
|
|
1407
|
-
type: 'Identifier',
|
|
1408
|
-
decorators: [],
|
|
1409
|
-
name: SPECIFIER,
|
|
1410
|
-
optional: false,
|
|
1411
|
-
loc: DUMMY_LOC,
|
|
1412
|
-
},
|
|
1413
|
-
typeAnnotation: {
|
|
1414
|
-
type: 'TSTypeQuery',
|
|
1415
|
-
exprName: {
|
|
1416
|
-
type: 'Identifier',
|
|
1417
|
-
decorators: [],
|
|
1418
|
-
name: SPECIFIER,
|
|
1419
|
-
optional: false,
|
|
1420
|
-
loc: DUMMY_LOC,
|
|
1421
|
-
},
|
|
1422
|
-
loc: DUMMY_LOC,
|
|
1423
|
-
},
|
|
1424
|
-
loc: DUMMY_LOC,
|
|
1425
|
-
},
|
|
1529
|
+
...declareTypeAsVariable(SPECIFIER, declaration),
|
|
1426
1530
|
{
|
|
1427
1531
|
type: 'ExportDefaultDeclaration',
|
|
1428
1532
|
loc: DUMMY_LOC,
|
|
@@ -1494,6 +1598,17 @@ const getTransforms = (
|
|
|
1494
1598
|
exportKind: 'type',
|
|
1495
1599
|
},
|
|
1496
1600
|
];
|
|
1601
|
+
case 'DeclareNamespace':
|
|
1602
|
+
return [
|
|
1603
|
+
{
|
|
1604
|
+
declaration: unsupportedDeclaration(
|
|
1605
|
+
node.declaration,
|
|
1606
|
+
'namespaces',
|
|
1607
|
+
node.declaration.id,
|
|
1608
|
+
),
|
|
1609
|
+
exportKind: 'value',
|
|
1610
|
+
},
|
|
1611
|
+
];
|
|
1497
1612
|
case 'DeclareOpaqueType':
|
|
1498
1613
|
return [
|
|
1499
1614
|
{
|
|
@@ -1788,11 +1903,12 @@ const getTransforms = (
|
|
|
1788
1903
|
DeclareFunction(
|
|
1789
1904
|
node: FlowESTree.DeclareFunction,
|
|
1790
1905
|
): TSESTree.TSDeclareFunction {
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
|
|
1906
|
+
const annotation = node.id?.typeAnnotation ?? node.typeAnnotation;
|
|
1907
|
+
if (annotation == null) {
|
|
1908
|
+
throw translationError(node, 'Declare function is missing its type');
|
|
1909
|
+
}
|
|
1910
|
+
const functionType = annotation.typeAnnotation;
|
|
1911
|
+
const functionInfo = transform.FunctionTypeAnnotation(functionType);
|
|
1796
1912
|
|
|
1797
1913
|
return {
|
|
1798
1914
|
type: 'TSDeclareFunction',
|
|
@@ -1802,11 +1918,14 @@ const getTransforms = (
|
|
|
1802
1918
|
declare: true,
|
|
1803
1919
|
expression: false,
|
|
1804
1920
|
generator: false,
|
|
1805
|
-
id:
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
|
|
1809
|
-
|
|
1921
|
+
id:
|
|
1922
|
+
node.id == null
|
|
1923
|
+
? null
|
|
1924
|
+
: {
|
|
1925
|
+
type: 'Identifier',
|
|
1926
|
+
loc: DUMMY_LOC,
|
|
1927
|
+
name: node.id.name,
|
|
1928
|
+
},
|
|
1810
1929
|
params: functionInfo.params,
|
|
1811
1930
|
returnType: functionInfo.returnType,
|
|
1812
1931
|
typeParameters: functionInfo.typeParameters,
|
|
@@ -1974,8 +2093,65 @@ const getTransforms = (
|
|
|
1974
2093
|
},
|
|
1975
2094
|
DeclareModuleExports(
|
|
1976
2095
|
node: FlowESTree.DeclareModuleExports,
|
|
1977
|
-
):
|
|
1978
|
-
|
|
2096
|
+
):
|
|
2097
|
+
| TSESTree.TSExportAssignment
|
|
2098
|
+
| [
|
|
2099
|
+
TSESTree.VariableDeclaration,
|
|
2100
|
+
TSESTree.TSTypeAliasDeclaration,
|
|
2101
|
+
TSESTree.TSExportAssignment,
|
|
2102
|
+
] {
|
|
2103
|
+
// TS forbids `export = ` in a module that has any other export, so a
|
|
2104
|
+
// module combining the two has no faithful translation.
|
|
2105
|
+
if (
|
|
2106
|
+
node.parent.type === 'Program' &&
|
|
2107
|
+
node.parent.body.some(
|
|
2108
|
+
statement =>
|
|
2109
|
+
statement.type === 'DeclareExportAllDeclaration' ||
|
|
2110
|
+
statement.type === 'DeclareExportDeclaration' ||
|
|
2111
|
+
statement.type === 'ExportAllDeclaration' ||
|
|
2112
|
+
statement.type === 'ExportDefaultDeclaration' ||
|
|
2113
|
+
statement.type === 'ExportNamedDeclaration',
|
|
2114
|
+
)
|
|
2115
|
+
) {
|
|
2116
|
+
throw translationError(
|
|
2117
|
+
node,
|
|
2118
|
+
'CommonJS exports cannot be combined with ES module exports.',
|
|
2119
|
+
);
|
|
2120
|
+
}
|
|
2121
|
+
|
|
2122
|
+
// `declare module.exports: T` is TS's `export = <value>`, which - like
|
|
2123
|
+
// `export default` - can only name a value.
|
|
2124
|
+
const type = node.typeAnnotation.typeAnnotation;
|
|
2125
|
+
|
|
2126
|
+
if (
|
|
2127
|
+
type.type === 'TypeofTypeAnnotation' &&
|
|
2128
|
+
type.argument.type === 'Identifier' &&
|
|
2129
|
+
isDeclaredClass(type.argument.name)
|
|
2130
|
+
) {
|
|
2131
|
+
return {
|
|
2132
|
+
type: 'TSExportAssignment',
|
|
2133
|
+
loc: DUMMY_LOC,
|
|
2134
|
+
expression: {
|
|
2135
|
+
type: 'Identifier',
|
|
2136
|
+
loc: DUMMY_LOC,
|
|
2137
|
+
name: type.argument.name,
|
|
2138
|
+
},
|
|
2139
|
+
};
|
|
2140
|
+
}
|
|
2141
|
+
|
|
2142
|
+
const SPECIFIER = '$$MODULE_EXPORTS$$';
|
|
2143
|
+
return [
|
|
2144
|
+
...declareTypeAsVariable(SPECIFIER, type),
|
|
2145
|
+
{
|
|
2146
|
+
type: 'TSExportAssignment',
|
|
2147
|
+
loc: DUMMY_LOC,
|
|
2148
|
+
expression: {
|
|
2149
|
+
type: 'Identifier',
|
|
2150
|
+
loc: DUMMY_LOC,
|
|
2151
|
+
name: SPECIFIER,
|
|
2152
|
+
},
|
|
2153
|
+
},
|
|
2154
|
+
];
|
|
1979
2155
|
},
|
|
1980
2156
|
ExistsTypeAnnotation(
|
|
1981
2157
|
node: FlowESTree.ExistsTypeAnnotation,
|
|
@@ -2086,8 +2262,48 @@ const getTransforms = (
|
|
|
2086
2262
|
loc: DUMMY_LOC,
|
|
2087
2263
|
exported: transform.Identifier(node.exported, false),
|
|
2088
2264
|
local: transform.Identifier(node.local, false),
|
|
2089
|
-
|
|
2090
|
-
|
|
2265
|
+
exportKind: node.exportKind,
|
|
2266
|
+
};
|
|
2267
|
+
},
|
|
2268
|
+
ConstructorTypeAnnotation(
|
|
2269
|
+
node: FlowESTree.ConstructorTypeAnnotation,
|
|
2270
|
+
): TSESTree.TSConstructorType {
|
|
2271
|
+
const params = node.params.map(transform.FunctionTypeParam);
|
|
2272
|
+
if (node.rest != null) {
|
|
2273
|
+
const rest = node.rest;
|
|
2274
|
+
params.push({
|
|
2275
|
+
type: 'RestElement',
|
|
2276
|
+
loc: DUMMY_LOC,
|
|
2277
|
+
argument:
|
|
2278
|
+
rest.name == null
|
|
2279
|
+
? {
|
|
2280
|
+
type: 'Identifier',
|
|
2281
|
+
loc: DUMMY_LOC,
|
|
2282
|
+
name: '$$REST$$',
|
|
2283
|
+
}
|
|
2284
|
+
: transform.Identifier(rest.name, false),
|
|
2285
|
+
typeAnnotation: {
|
|
2286
|
+
type: 'TSTypeAnnotation',
|
|
2287
|
+
loc: DUMMY_LOC,
|
|
2288
|
+
typeAnnotation: transformTypeAnnotationType(rest.typeAnnotation),
|
|
2289
|
+
},
|
|
2290
|
+
});
|
|
2291
|
+
}
|
|
2292
|
+
|
|
2293
|
+
return {
|
|
2294
|
+
type: 'TSConstructorType',
|
|
2295
|
+
loc: DUMMY_LOC,
|
|
2296
|
+
abstract: node.abstract,
|
|
2297
|
+
params,
|
|
2298
|
+
returnType: {
|
|
2299
|
+
type: 'TSTypeAnnotation',
|
|
2300
|
+
loc: DUMMY_LOC,
|
|
2301
|
+
typeAnnotation: transformTypeAnnotationType(node.returnType),
|
|
2302
|
+
},
|
|
2303
|
+
typeParameters:
|
|
2304
|
+
node.typeParameters == null
|
|
2305
|
+
? undefined
|
|
2306
|
+
: transform.TypeParameterDeclaration(node.typeParameters),
|
|
2091
2307
|
};
|
|
2092
2308
|
},
|
|
2093
2309
|
FunctionTypeAnnotation(
|
|
@@ -2136,7 +2352,10 @@ const getTransforms = (
|
|
|
2136
2352
|
returnType: {
|
|
2137
2353
|
type: 'TSTypeAnnotation',
|
|
2138
2354
|
loc: DUMMY_LOC,
|
|
2139
|
-
typeAnnotation:
|
|
2355
|
+
typeAnnotation:
|
|
2356
|
+
node.returnType == null
|
|
2357
|
+
? {type: 'TSAnyKeyword', loc: DUMMY_LOC}
|
|
2358
|
+
: transformTypeAnnotationType(node.returnType),
|
|
2140
2359
|
},
|
|
2141
2360
|
typeParameters:
|
|
2142
2361
|
node.typeParameters == null
|
|
@@ -2163,6 +2382,14 @@ const getTransforms = (
|
|
|
2163
2382
|
GenericTypeAnnotation(
|
|
2164
2383
|
node: FlowESTree.GenericTypeAnnotation,
|
|
2165
2384
|
): TSESTree.TypeNode {
|
|
2385
|
+
const importType = transformImportTypeReference(
|
|
2386
|
+
node.id,
|
|
2387
|
+
transform.TypeParameterInstantiation(node.typeParameters) ?? null,
|
|
2388
|
+
);
|
|
2389
|
+
if (importType != null) {
|
|
2390
|
+
return importType;
|
|
2391
|
+
}
|
|
2392
|
+
|
|
2166
2393
|
const [fullTypeName, baseId] = (() => {
|
|
2167
2394
|
let names: Array<string> = [];
|
|
2168
2395
|
let currentNode = node.id;
|
|
@@ -3189,13 +3416,19 @@ const getTransforms = (
|
|
|
3189
3416
|
}
|
|
3190
3417
|
}
|
|
3191
3418
|
|
|
3419
|
+
const typeName =
|
|
3420
|
+
node.id.type === 'Identifier'
|
|
3421
|
+
? transform.Identifier(node.id, false)
|
|
3422
|
+
: node.id.type === 'QualifiedTypeIdentifier'
|
|
3423
|
+
? transform.QualifiedTypeIdentifier(node.id)
|
|
3424
|
+
: null;
|
|
3425
|
+
if (typeName == null) {
|
|
3426
|
+
throw unexpectedTranslationError(node, 'Unreachable import type');
|
|
3427
|
+
}
|
|
3192
3428
|
return {
|
|
3193
3429
|
type: 'TSTypeReference',
|
|
3194
3430
|
loc: DUMMY_LOC,
|
|
3195
|
-
typeName
|
|
3196
|
-
node.id.type === 'Identifier'
|
|
3197
|
-
? transform.Identifier(node.id, false)
|
|
3198
|
-
: transform.QualifiedTypeIdentifier(node.id),
|
|
3431
|
+
typeName,
|
|
3199
3432
|
typeArguments: transform.TypeParameterInstantiation(
|
|
3200
3433
|
node.typeParameters,
|
|
3201
3434
|
),
|
|
@@ -3503,11 +3736,15 @@ const getTransforms = (
|
|
|
3503
3736
|
},
|
|
3504
3737
|
constraint: transformTypeAnnotationType(prop.sourceType),
|
|
3505
3738
|
readonly:
|
|
3506
|
-
prop.
|
|
3507
|
-
prop.variance?.kind === '
|
|
3739
|
+
prop.varianceOp ??
|
|
3740
|
+
(prop.variance?.kind === 'plus' ||
|
|
3741
|
+
prop.variance?.kind === 'readonly'),
|
|
3508
3742
|
optional: prop.optional === 'Optional',
|
|
3509
3743
|
typeAnnotation: transformTypeAnnotationType(prop.propType),
|
|
3510
|
-
nameType:
|
|
3744
|
+
nameType:
|
|
3745
|
+
prop.nameType == null
|
|
3746
|
+
? null
|
|
3747
|
+
: transformTypeAnnotationType(prop.nameType),
|
|
3511
3748
|
};
|
|
3512
3749
|
|
|
3513
3750
|
return tsProp;
|
|
@@ -3557,6 +3794,10 @@ const getTransforms = (
|
|
|
3557
3794
|
);
|
|
3558
3795
|
}
|
|
3559
3796
|
|
|
3797
|
+
if (property.type === 'ObjectTypePrivateField') {
|
|
3798
|
+
return unsupportedAnnotation(property, 'private type fields');
|
|
3799
|
+
}
|
|
3800
|
+
|
|
3560
3801
|
members.push({
|
|
3561
3802
|
start: property.range[0],
|
|
3562
3803
|
node: transform.ObjectTypeProperty(property),
|
|
@@ -3678,6 +3919,8 @@ const getTransforms = (
|
|
|
3678
3919
|
property,
|
|
3679
3920
|
'object type with mapped type property',
|
|
3680
3921
|
);
|
|
3922
|
+
} else if (property.type === 'ObjectTypePrivateField') {
|
|
3923
|
+
return unsupportedAnnotation(property, 'private type fields');
|
|
3681
3924
|
} else {
|
|
3682
3925
|
members.push({
|
|
3683
3926
|
start: property.range[0],
|
|
@@ -3772,6 +4015,9 @@ const getTransforms = (
|
|
|
3772
4015
|
node: FlowESTree.ObjectTypeIndexer,
|
|
3773
4016
|
): TSESTree.TSIndexSignature | TSESTree.TSPropertySignatureComputedName {
|
|
3774
4017
|
if (node.key.type === 'GenericTypeAnnotation') {
|
|
4018
|
+
if (node.key.id.type === 'ImportType') {
|
|
4019
|
+
throw translationError(node, 'Unsupported import type indexer key');
|
|
4020
|
+
}
|
|
3775
4021
|
const ident =
|
|
3776
4022
|
node.key.id.type === 'Identifier' ? node.key.id : node.key.id.id;
|
|
3777
4023
|
return {
|
|
@@ -3975,14 +4221,18 @@ const getTransforms = (
|
|
|
3975
4221
|
node: FlowESTree.QualifiedTypeIdentifier,
|
|
3976
4222
|
): TSESTree.TSQualifiedName {
|
|
3977
4223
|
const qual = node.qualification;
|
|
4224
|
+
if (qual.type === 'ImportType') {
|
|
4225
|
+
throw unexpectedTranslationError(qual, 'Unreachable import type');
|
|
4226
|
+
}
|
|
4227
|
+
const left =
|
|
4228
|
+
qual.type === 'Identifier'
|
|
4229
|
+
? transform.Identifier(qual, false)
|
|
4230
|
+
: transform.QualifiedTypeIdentifier(qual);
|
|
3978
4231
|
|
|
3979
4232
|
return {
|
|
3980
4233
|
type: 'TSQualifiedName',
|
|
3981
4234
|
loc: DUMMY_LOC,
|
|
3982
|
-
left
|
|
3983
|
-
qual.type === 'Identifier'
|
|
3984
|
-
? transform.Identifier(qual, false)
|
|
3985
|
-
: transform.QualifiedTypeIdentifier(qual),
|
|
4235
|
+
left,
|
|
3986
4236
|
right: transform.Identifier(node.id, false),
|
|
3987
4237
|
};
|
|
3988
4238
|
},
|
|
@@ -3990,14 +4240,18 @@ const getTransforms = (
|
|
|
3990
4240
|
node: FlowESTree.QualifiedTypeofIdentifier,
|
|
3991
4241
|
): TSESTree.TSQualifiedName {
|
|
3992
4242
|
const qual = node.qualification;
|
|
4243
|
+
if (qual.type === 'ImportType') {
|
|
4244
|
+
throw unexpectedTranslationError(qual, 'Unreachable import type');
|
|
4245
|
+
}
|
|
4246
|
+
const left =
|
|
4247
|
+
qual.type === 'Identifier'
|
|
4248
|
+
? transform.Identifier(qual, false)
|
|
4249
|
+
: transform.QualifiedTypeofIdentifier(qual);
|
|
3993
4250
|
|
|
3994
4251
|
return {
|
|
3995
4252
|
type: 'TSQualifiedName',
|
|
3996
4253
|
loc: DUMMY_LOC,
|
|
3997
|
-
left
|
|
3998
|
-
qual.type === 'Identifier'
|
|
3999
|
-
? transform.Identifier(qual, false)
|
|
4000
|
-
: transform.QualifiedTypeofIdentifier(qual),
|
|
4254
|
+
left,
|
|
4001
4255
|
right: transform.Identifier(node.id, false),
|
|
4002
4256
|
};
|
|
4003
4257
|
},
|
|
@@ -4059,6 +4313,24 @@ const getTransforms = (
|
|
|
4059
4313
|
loc: DUMMY_LOC,
|
|
4060
4314
|
};
|
|
4061
4315
|
},
|
|
4316
|
+
TemplateLiteralTypeAnnotation(
|
|
4317
|
+
node: FlowESTree.TemplateLiteralTypeAnnotation,
|
|
4318
|
+
): TSESTree.TSTemplateLiteralType {
|
|
4319
|
+
return {
|
|
4320
|
+
type: 'TSTemplateLiteralType',
|
|
4321
|
+
loc: DUMMY_LOC,
|
|
4322
|
+
quasis: node.quasis.map(quasi => ({
|
|
4323
|
+
type: 'TemplateElement',
|
|
4324
|
+
loc: DUMMY_LOC,
|
|
4325
|
+
tail: quasi.tail,
|
|
4326
|
+
value: {
|
|
4327
|
+
cooked: quasi.value.cooked,
|
|
4328
|
+
raw: quasi.value.raw,
|
|
4329
|
+
},
|
|
4330
|
+
})),
|
|
4331
|
+
types: node.types.map(transformTypeAnnotationType),
|
|
4332
|
+
};
|
|
4333
|
+
},
|
|
4062
4334
|
TupleTypeAnnotation(
|
|
4063
4335
|
node: FlowESTree.TupleTypeAnnotation,
|
|
4064
4336
|
): TSESTree.TSTupleType | TSESTree.TSTypeOperator {
|
|
@@ -4141,6 +4413,16 @@ const getTransforms = (
|
|
|
4141
4413
|
}
|
|
4142
4414
|
: tupleAnnot;
|
|
4143
4415
|
},
|
|
4416
|
+
TupleTypeElement(node: FlowESTree.TupleTypeElement): TSESTree.TypeNode {
|
|
4417
|
+
const elementType = transformTypeAnnotationType(node.elementType);
|
|
4418
|
+
return node.optional
|
|
4419
|
+
? {
|
|
4420
|
+
type: 'TSOptionalType',
|
|
4421
|
+
loc: DUMMY_LOC,
|
|
4422
|
+
typeAnnotation: elementType,
|
|
4423
|
+
}
|
|
4424
|
+
: elementType;
|
|
4425
|
+
},
|
|
4144
4426
|
TypeAlias(node: FlowESTree.TypeAlias): TSESTree.TSTypeAliasDeclaration {
|
|
4145
4427
|
return transform.DeclareTypeAlias(node);
|
|
4146
4428
|
},
|
|
@@ -4154,6 +4436,30 @@ const getTransforms = (
|
|
|
4154
4436
|
TypeofTypeAnnotation(
|
|
4155
4437
|
node: FlowESTree.TypeofTypeAnnotation,
|
|
4156
4438
|
): TSESTree.TSTypeQuery {
|
|
4439
|
+
if (node.argument.type === 'ImportType') {
|
|
4440
|
+
const importType = transformImportTypeReference(node.argument);
|
|
4441
|
+
if (importType == null) {
|
|
4442
|
+
throw unexpectedTranslationError(node, 'Invalid import type');
|
|
4443
|
+
}
|
|
4444
|
+
return {
|
|
4445
|
+
type: 'TSTypeQuery',
|
|
4446
|
+
loc: DUMMY_LOC,
|
|
4447
|
+
exprName: importType,
|
|
4448
|
+
typeArguments: undefined,
|
|
4449
|
+
};
|
|
4450
|
+
}
|
|
4451
|
+
const importType =
|
|
4452
|
+
node.argument.type === 'QualifiedTypeofIdentifier'
|
|
4453
|
+
? transformImportTypeReference(node.argument)
|
|
4454
|
+
: null;
|
|
4455
|
+
if (importType != null) {
|
|
4456
|
+
return {
|
|
4457
|
+
type: 'TSTypeQuery',
|
|
4458
|
+
loc: DUMMY_LOC,
|
|
4459
|
+
exprName: importType,
|
|
4460
|
+
typeArguments: undefined,
|
|
4461
|
+
};
|
|
4462
|
+
}
|
|
4157
4463
|
switch (node.argument.type) {
|
|
4158
4464
|
case 'Identifier':
|
|
4159
4465
|
return {
|
|
@@ -4169,6 +4475,11 @@ const getTransforms = (
|
|
|
4169
4475
|
exprName: transform.QualifiedTypeofIdentifier(node.argument),
|
|
4170
4476
|
typeArguments: undefined,
|
|
4171
4477
|
};
|
|
4478
|
+
default:
|
|
4479
|
+
throw unexpectedTranslationError(
|
|
4480
|
+
node.argument,
|
|
4481
|
+
'Unexpected typeof annotation argument',
|
|
4482
|
+
);
|
|
4172
4483
|
}
|
|
4173
4484
|
},
|
|
4174
4485
|
TypeParameter(node: FlowESTree.TypeParameter): TSESTree.TSTypeParameter {
|
|
@@ -4326,8 +4637,15 @@ const getTransforms = (
|
|
|
4326
4637
|
typeAnnotation: transformTypeAnnotationType(node.argument),
|
|
4327
4638
|
};
|
|
4328
4639
|
},
|
|
4329
|
-
TypeOperator(node: FlowESTree.
|
|
4640
|
+
TypeOperator(node: FlowESTree.TypeOperator): TSESTree.TypeNode {
|
|
4330
4641
|
switch (node.operator) {
|
|
4642
|
+
case 'unique':
|
|
4643
|
+
return {
|
|
4644
|
+
type: 'TSTypeOperator',
|
|
4645
|
+
loc: DUMMY_LOC,
|
|
4646
|
+
operator: 'unique',
|
|
4647
|
+
typeAnnotation: transformTypeAnnotationType(node.typeAnnotation),
|
|
4648
|
+
};
|
|
4331
4649
|
case 'renders':
|
|
4332
4650
|
case 'renders?':
|
|
4333
4651
|
case 'renders*': {
|