flow-api-translator 0.15.0 → 0.16.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/dist/flowDefToTSDef.js +328 -40
- package/dist/flowDefToTSDef.js.flow +362 -40
- package/dist/flowToFlowDef.js +120 -3
- package/dist/flowToFlowDef.js.flow +164 -3
- package/dist/flowToJS.js +11 -160
- package/dist/flowToJS.js.flow +17 -139
- package/dist/utils/ts-estree-ast-types.js.flow +3 -3
- package/package.json +5 -5
|
@@ -11,24 +11,32 @@
|
|
|
11
11
|
'use strict';
|
|
12
12
|
|
|
13
13
|
import type {ObjectWithLoc} from 'hermes-estree';
|
|
14
|
-
import
|
|
14
|
+
import type {TranslationOptions} from './utils/TranslationUtils';
|
|
15
15
|
import type {ScopeManager} from 'hermes-eslint';
|
|
16
|
+
|
|
17
|
+
import * as FlowESTree from 'hermes-estree';
|
|
18
|
+
import * as TSESTree from './utils/ts-estree-ast-types';
|
|
16
19
|
import {
|
|
17
20
|
cloneJSDocCommentsToNewNode as cloneJSDocCommentsToNewNodeOriginal,
|
|
18
21
|
makeCommentOwnLine as makeCommentOwnLineOriginal,
|
|
19
22
|
} from 'hermes-transform';
|
|
20
|
-
import * as TSESTree from './utils/ts-estree-ast-types';
|
|
21
23
|
import {
|
|
22
24
|
buildCodeFrame,
|
|
23
25
|
translationError as translationErrorBase,
|
|
24
26
|
unexpectedTranslationError as unexpectedTranslationErrorBase,
|
|
25
27
|
} from './utils/ErrorUtils';
|
|
26
28
|
import {removeAtFlowFromDocblock} from './utils/DocblockUtils';
|
|
27
|
-
import type {TranslationOptions} from './utils/TranslationUtils';
|
|
28
29
|
import {EOL} from 'os';
|
|
29
30
|
|
|
30
31
|
type DeclarationOrUnsupported<T> = T | TSESTree.TSTypeAliasDeclaration;
|
|
31
32
|
|
|
33
|
+
function constructFlowNode<T: FlowESTree.BaseNode>(
|
|
34
|
+
node: $Diff<T, FlowESTree.BaseNode>,
|
|
35
|
+
): T {
|
|
36
|
+
// $FlowFixMe[prop-missing]
|
|
37
|
+
return node;
|
|
38
|
+
}
|
|
39
|
+
|
|
32
40
|
const cloneJSDocCommentsToNewNode =
|
|
33
41
|
// $FlowExpectedError[incompatible-cast] - trust me this re-type is 100% safe
|
|
34
42
|
(cloneJSDocCommentsToNewNodeOriginal: (mixed, mixed) => void);
|
|
@@ -45,6 +53,19 @@ function isValidReactImportOrGlobal(id: FlowESTree.Identifier): boolean {
|
|
|
45
53
|
|
|
46
54
|
let shouldAddReactImport: boolean | null = null;
|
|
47
55
|
|
|
56
|
+
// Returns appropriate Identifier for `React` import.
|
|
57
|
+
// If a global is in use, set a flag to indicate that we should add the import.
|
|
58
|
+
function getReactIdentifier(hasReactImport: boolean) {
|
|
59
|
+
if (shouldAddReactImport !== false) {
|
|
60
|
+
shouldAddReactImport = !hasReactImport;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
return {
|
|
64
|
+
type: 'Identifier',
|
|
65
|
+
name: `React`,
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
|
|
48
69
|
export function flowDefToTSDef(
|
|
49
70
|
originalCode: string,
|
|
50
71
|
ast: FlowESTree.Program,
|
|
@@ -204,10 +225,10 @@ const getTransforms = (
|
|
|
204
225
|
return globalScope;
|
|
205
226
|
})();
|
|
206
227
|
|
|
207
|
-
function isReactImport(
|
|
228
|
+
function isReactImport(scopeNode: FlowESTree.ESNode, name: string): boolean {
|
|
208
229
|
let currentScope = (() => {
|
|
209
230
|
let scope = null;
|
|
210
|
-
let node: FlowESTree.ESNode =
|
|
231
|
+
let node: FlowESTree.ESNode = scopeNode;
|
|
211
232
|
while (!scope && node) {
|
|
212
233
|
scope = scopeManager.acquire(node, true);
|
|
213
234
|
node = node.parent;
|
|
@@ -223,7 +244,7 @@ const getTransforms = (
|
|
|
223
244
|
const variableDef = (() => {
|
|
224
245
|
while (currentScope != null) {
|
|
225
246
|
for (const variable of currentScope.variables) {
|
|
226
|
-
if (variable.defs.length && variable.name ===
|
|
247
|
+
if (variable.defs.length && variable.name === name) {
|
|
227
248
|
return variable;
|
|
228
249
|
}
|
|
229
250
|
}
|
|
@@ -254,7 +275,7 @@ const getTransforms = (
|
|
|
254
275
|
|
|
255
276
|
// Globals
|
|
256
277
|
case 'ImplicitGlobalVariable': {
|
|
257
|
-
return VALID_REACT_IMPORTS.has(
|
|
278
|
+
return VALID_REACT_IMPORTS.has(name);
|
|
258
279
|
}
|
|
259
280
|
|
|
260
281
|
// TODO Handle:
|
|
@@ -657,7 +678,17 @@ const getTransforms = (
|
|
|
657
678
|
case 'VoidTypeAnnotation':
|
|
658
679
|
return transform.VoidTypeAnnotation(node);
|
|
659
680
|
case 'TypePredicate':
|
|
660
|
-
return
|
|
681
|
+
return transform.TypePredicateAnnotation(node);
|
|
682
|
+
case 'ConditionalTypeAnnotation':
|
|
683
|
+
return transform.ConditionalTypeAnnotation(node);
|
|
684
|
+
case 'InferTypeAnnotation':
|
|
685
|
+
return transform.InferTypeAnnotation(node);
|
|
686
|
+
case 'KeyofTypeAnnotation':
|
|
687
|
+
return transform.KeyofTypeAnnotation(node);
|
|
688
|
+
case 'TypeOperator':
|
|
689
|
+
return transform.TypeOperator(node);
|
|
690
|
+
case 'ComponentTypeAnnotation':
|
|
691
|
+
return transform.ComponentTypeAnnotation(node);
|
|
661
692
|
default:
|
|
662
693
|
throw unexpectedTranslationError(node, `Unhandled type ${node.type}`);
|
|
663
694
|
}
|
|
@@ -986,6 +1017,23 @@ const getTransforms = (
|
|
|
986
1017
|
];
|
|
987
1018
|
}
|
|
988
1019
|
|
|
1020
|
+
// TS doesn't support direct default export for declare'd functions
|
|
1021
|
+
case 'DeclareComponent': {
|
|
1022
|
+
const functionDecl = transform.DeclareComponent(declaration);
|
|
1023
|
+
const name = declaration.id.name;
|
|
1024
|
+
return [
|
|
1025
|
+
functionDecl,
|
|
1026
|
+
{
|
|
1027
|
+
type: 'ExportDefaultDeclaration',
|
|
1028
|
+
declaration: {
|
|
1029
|
+
type: 'Identifier',
|
|
1030
|
+
name,
|
|
1031
|
+
},
|
|
1032
|
+
exportKind: 'value',
|
|
1033
|
+
},
|
|
1034
|
+
];
|
|
1035
|
+
}
|
|
1036
|
+
|
|
989
1037
|
// Flow's declare export default Identifier is ambiguous.
|
|
990
1038
|
// the Identifier might reference a type, or it might reference a value
|
|
991
1039
|
// - If it's a value, then that's all good, TS supports that.
|
|
@@ -1122,6 +1170,13 @@ const getTransforms = (
|
|
|
1122
1170
|
exportKind: 'value',
|
|
1123
1171
|
},
|
|
1124
1172
|
];
|
|
1173
|
+
case 'DeclareComponent':
|
|
1174
|
+
return [
|
|
1175
|
+
{
|
|
1176
|
+
declaration: transform.DeclareComponent(node.declaration),
|
|
1177
|
+
exportKind: 'value',
|
|
1178
|
+
},
|
|
1179
|
+
];
|
|
1125
1180
|
case 'DeclareFunction':
|
|
1126
1181
|
return [
|
|
1127
1182
|
{
|
|
@@ -1194,6 +1249,134 @@ const getTransforms = (
|
|
|
1194
1249
|
}
|
|
1195
1250
|
}
|
|
1196
1251
|
},
|
|
1252
|
+
DeclareComponent(
|
|
1253
|
+
node: FlowESTree.DeclareComponent,
|
|
1254
|
+
): TSESTree.TSDeclareFunction {
|
|
1255
|
+
const id = transform.Identifier(node.id, false);
|
|
1256
|
+
|
|
1257
|
+
const typeParameters =
|
|
1258
|
+
node.typeParameters == null
|
|
1259
|
+
? undefined
|
|
1260
|
+
: transform.TypeParameterDeclaration(node.typeParameters);
|
|
1261
|
+
|
|
1262
|
+
const params = transform.ComponentTypeParameters(node.params, node.rest);
|
|
1263
|
+
|
|
1264
|
+
// TS cannot support `renderType` so we always use ReactNode as the return type.
|
|
1265
|
+
const hasReactImport = isReactImport(node, 'React');
|
|
1266
|
+
const returnType = {
|
|
1267
|
+
type: 'TSTypeAnnotation',
|
|
1268
|
+
// If no rendersType we assume its ReactNode type.
|
|
1269
|
+
typeAnnotation: {
|
|
1270
|
+
type: 'TSTypeReference',
|
|
1271
|
+
typeName: {
|
|
1272
|
+
type: 'TSQualifiedName',
|
|
1273
|
+
left: getReactIdentifier(hasReactImport),
|
|
1274
|
+
right: {
|
|
1275
|
+
type: 'Identifier',
|
|
1276
|
+
name: `ReactNode`,
|
|
1277
|
+
},
|
|
1278
|
+
},
|
|
1279
|
+
typeParameters: undefined,
|
|
1280
|
+
},
|
|
1281
|
+
};
|
|
1282
|
+
|
|
1283
|
+
return {
|
|
1284
|
+
type: 'TSDeclareFunction',
|
|
1285
|
+
async: false,
|
|
1286
|
+
body: undefined,
|
|
1287
|
+
declare: true,
|
|
1288
|
+
expression: false,
|
|
1289
|
+
generator: false,
|
|
1290
|
+
id: {
|
|
1291
|
+
type: 'Identifier',
|
|
1292
|
+
name: id.name,
|
|
1293
|
+
},
|
|
1294
|
+
params,
|
|
1295
|
+
returnType: returnType,
|
|
1296
|
+
typeParameters: typeParameters,
|
|
1297
|
+
};
|
|
1298
|
+
},
|
|
1299
|
+
ComponentTypeParameters(
|
|
1300
|
+
params: $ReadOnlyArray<FlowESTree.ComponentTypeParameter>,
|
|
1301
|
+
rest: FlowESTree.ComponentTypeParameter | null,
|
|
1302
|
+
): $ReadOnlyArray<TSESTree.Parameter> {
|
|
1303
|
+
if (params.length === 0 && rest != null) {
|
|
1304
|
+
return [
|
|
1305
|
+
{
|
|
1306
|
+
type: 'Identifier',
|
|
1307
|
+
name: 'props',
|
|
1308
|
+
typeAnnotation: {
|
|
1309
|
+
type: 'TSTypeAnnotation',
|
|
1310
|
+
typeAnnotation: transformTypeAnnotationType(rest.typeAnnotation),
|
|
1311
|
+
},
|
|
1312
|
+
optional: false,
|
|
1313
|
+
},
|
|
1314
|
+
];
|
|
1315
|
+
}
|
|
1316
|
+
|
|
1317
|
+
const flowPropsType: Array<
|
|
1318
|
+
FlowESTree.ObjectTypeProperty | FlowESTree.ObjectTypeSpreadProperty,
|
|
1319
|
+
> = [];
|
|
1320
|
+
|
|
1321
|
+
if (rest != null) {
|
|
1322
|
+
flowPropsType.push(
|
|
1323
|
+
constructFlowNode<FlowESTree.ObjectTypeSpreadProperty>({
|
|
1324
|
+
type: 'ObjectTypeSpreadProperty',
|
|
1325
|
+
argument: rest.typeAnnotation,
|
|
1326
|
+
range: rest.range,
|
|
1327
|
+
loc: rest.loc,
|
|
1328
|
+
}),
|
|
1329
|
+
);
|
|
1330
|
+
}
|
|
1331
|
+
|
|
1332
|
+
for (let i = 0; i < params.length; i++) {
|
|
1333
|
+
const param = params[i];
|
|
1334
|
+
flowPropsType.push(
|
|
1335
|
+
constructFlowNode<FlowESTree.ObjectTypePropertySignature>({
|
|
1336
|
+
type: 'ObjectTypeProperty',
|
|
1337
|
+
kind: 'init',
|
|
1338
|
+
method: false,
|
|
1339
|
+
optional: param.optional,
|
|
1340
|
+
variance: null,
|
|
1341
|
+
proto: false,
|
|
1342
|
+
static: false,
|
|
1343
|
+
key:
|
|
1344
|
+
param.name ??
|
|
1345
|
+
constructFlowNode<FlowESTree.Identifier>({
|
|
1346
|
+
type: 'Identifier',
|
|
1347
|
+
name: `$$PARAM_${i}$$`,
|
|
1348
|
+
optional: false,
|
|
1349
|
+
typeAnnotation: null,
|
|
1350
|
+
}),
|
|
1351
|
+
value: param.typeAnnotation,
|
|
1352
|
+
range: param.range,
|
|
1353
|
+
loc: param.loc,
|
|
1354
|
+
}),
|
|
1355
|
+
);
|
|
1356
|
+
}
|
|
1357
|
+
const tsPropsObjectType = transform.ObjectTypeAnnotation(
|
|
1358
|
+
constructFlowNode<FlowESTree.ObjectTypeAnnotation>({
|
|
1359
|
+
type: 'ObjectTypeAnnotation',
|
|
1360
|
+
inexact: false,
|
|
1361
|
+
exact: true,
|
|
1362
|
+
properties: flowPropsType,
|
|
1363
|
+
indexers: [],
|
|
1364
|
+
callProperties: [],
|
|
1365
|
+
internalSlots: [],
|
|
1366
|
+
}),
|
|
1367
|
+
);
|
|
1368
|
+
return [
|
|
1369
|
+
{
|
|
1370
|
+
type: 'Identifier',
|
|
1371
|
+
name: 'props',
|
|
1372
|
+
typeAnnotation: {
|
|
1373
|
+
type: 'TSTypeAnnotation',
|
|
1374
|
+
typeAnnotation: tsPropsObjectType,
|
|
1375
|
+
},
|
|
1376
|
+
optional: false,
|
|
1377
|
+
},
|
|
1378
|
+
];
|
|
1379
|
+
},
|
|
1197
1380
|
DeclareFunction(
|
|
1198
1381
|
node: FlowESTree.DeclareFunction,
|
|
1199
1382
|
): TSESTree.TSDeclareFunction {
|
|
@@ -1657,7 +1840,7 @@ const getTransforms = (
|
|
|
1657
1840
|
return {
|
|
1658
1841
|
type: 'TSImportType',
|
|
1659
1842
|
isTypeOf: true,
|
|
1660
|
-
|
|
1843
|
+
argument: moduleName,
|
|
1661
1844
|
qualifier: null,
|
|
1662
1845
|
typeParameters: null,
|
|
1663
1846
|
};
|
|
@@ -1757,6 +1940,34 @@ const getTransforms = (
|
|
|
1757
1940
|
};
|
|
1758
1941
|
}
|
|
1759
1942
|
|
|
1943
|
+
case '$ReadOnlyMap': {
|
|
1944
|
+
return {
|
|
1945
|
+
type: 'TSTypeReference',
|
|
1946
|
+
typeName: {
|
|
1947
|
+
type: 'Identifier',
|
|
1948
|
+
name: 'ReadonlyMap',
|
|
1949
|
+
},
|
|
1950
|
+
typeParameters: {
|
|
1951
|
+
type: 'TSTypeParameterInstantiation',
|
|
1952
|
+
params: assertHasExactlyNTypeParameters(1),
|
|
1953
|
+
},
|
|
1954
|
+
};
|
|
1955
|
+
}
|
|
1956
|
+
|
|
1957
|
+
case '$ReadOnlySet': {
|
|
1958
|
+
return {
|
|
1959
|
+
type: 'TSTypeReference',
|
|
1960
|
+
typeName: {
|
|
1961
|
+
type: 'Identifier',
|
|
1962
|
+
name: 'ReadonlySet',
|
|
1963
|
+
},
|
|
1964
|
+
typeParameters: {
|
|
1965
|
+
type: 'TSTypeParameterInstantiation',
|
|
1966
|
+
params: assertHasExactlyNTypeParameters(1),
|
|
1967
|
+
},
|
|
1968
|
+
};
|
|
1969
|
+
}
|
|
1970
|
+
|
|
1760
1971
|
case '$Values': {
|
|
1761
1972
|
// `$Values<T>` => `T[keyof T]`
|
|
1762
1973
|
const transformedType = assertHasExactlyNTypeParameters(1)[0];
|
|
@@ -1812,21 +2023,8 @@ const getTransforms = (
|
|
|
1812
2023
|
|
|
1813
2024
|
// React special conversion:
|
|
1814
2025
|
const validReactImportOrGlobal = isValidReactImportOrGlobal(baseId);
|
|
1815
|
-
const
|
|
1816
|
-
if (validReactImportOrGlobal ||
|
|
1817
|
-
// Returns appropriate Identifier for `React` import.
|
|
1818
|
-
// If a global is in use, set a flag to indicate that we should add the import.
|
|
1819
|
-
const getReactIdentifier = () => {
|
|
1820
|
-
if (shouldAddReactImport !== false) {
|
|
1821
|
-
shouldAddReactImport = !reactImport;
|
|
1822
|
-
}
|
|
1823
|
-
|
|
1824
|
-
return {
|
|
1825
|
-
type: 'Identifier',
|
|
1826
|
-
name: `React`,
|
|
1827
|
-
};
|
|
1828
|
-
};
|
|
1829
|
-
|
|
2026
|
+
const hasReactImport = isReactImport(baseId, baseId.name);
|
|
2027
|
+
if (validReactImportOrGlobal || hasReactImport) {
|
|
1830
2028
|
switch (fullTypeName) {
|
|
1831
2029
|
// TODO: In flow this is `ChildrenArray<T> = T | $ReadOnlyArray<ChildrenArray<T>>`.
|
|
1832
2030
|
// The recursive nature of it is rarely needed, so we're simplifying this for now
|
|
@@ -1878,7 +2076,7 @@ const getTransforms = (
|
|
|
1878
2076
|
type: 'TSTypeReference',
|
|
1879
2077
|
typeName: {
|
|
1880
2078
|
type: 'TSQualifiedName',
|
|
1881
|
-
left: getReactIdentifier(),
|
|
2079
|
+
left: getReactIdentifier(hasReactImport),
|
|
1882
2080
|
right: {
|
|
1883
2081
|
type: 'Identifier',
|
|
1884
2082
|
name: 'Component',
|
|
@@ -1899,7 +2097,7 @@ const getTransforms = (
|
|
|
1899
2097
|
type: 'TSTypeReference',
|
|
1900
2098
|
typeName: {
|
|
1901
2099
|
type: 'TSQualifiedName',
|
|
1902
|
-
left: getReactIdentifier(),
|
|
2100
|
+
left: getReactIdentifier(hasReactImport),
|
|
1903
2101
|
right: {
|
|
1904
2102
|
type: 'Identifier',
|
|
1905
2103
|
name: `Context`,
|
|
@@ -1919,7 +2117,7 @@ const getTransforms = (
|
|
|
1919
2117
|
type: 'TSTypeReference',
|
|
1920
2118
|
typeName: {
|
|
1921
2119
|
type: 'TSQualifiedName',
|
|
1922
|
-
left: getReactIdentifier(),
|
|
2120
|
+
left: getReactIdentifier(hasReactImport),
|
|
1923
2121
|
right: {
|
|
1924
2122
|
type: 'Identifier',
|
|
1925
2123
|
name: 'Key',
|
|
@@ -1935,7 +2133,7 @@ const getTransforms = (
|
|
|
1935
2133
|
type: 'TSTypeReference',
|
|
1936
2134
|
typeName: {
|
|
1937
2135
|
type: 'TSQualifiedName',
|
|
1938
|
-
left: getReactIdentifier(),
|
|
2136
|
+
left: getReactIdentifier(hasReactImport),
|
|
1939
2137
|
right: {
|
|
1940
2138
|
type: 'Identifier',
|
|
1941
2139
|
name: `ElementType`,
|
|
@@ -1952,7 +2150,7 @@ const getTransforms = (
|
|
|
1952
2150
|
type: 'TSTypeReference',
|
|
1953
2151
|
typeName: {
|
|
1954
2152
|
type: 'TSQualifiedName',
|
|
1955
|
-
left: getReactIdentifier(),
|
|
2153
|
+
left: getReactIdentifier(hasReactImport),
|
|
1956
2154
|
right: {
|
|
1957
2155
|
type: 'Identifier',
|
|
1958
2156
|
name: `ReactNode`,
|
|
@@ -1968,7 +2166,7 @@ const getTransforms = (
|
|
|
1968
2166
|
type: 'TSTypeReference',
|
|
1969
2167
|
typeName: {
|
|
1970
2168
|
type: 'TSQualifiedName',
|
|
1971
|
-
left: getReactIdentifier(),
|
|
2169
|
+
left: getReactIdentifier(hasReactImport),
|
|
1972
2170
|
right: {
|
|
1973
2171
|
type: 'Identifier',
|
|
1974
2172
|
name: `ReactElement`,
|
|
@@ -1988,7 +2186,7 @@ const getTransforms = (
|
|
|
1988
2186
|
type: 'TSTypeReference',
|
|
1989
2187
|
typeName: {
|
|
1990
2188
|
type: 'TSQualifiedName',
|
|
1991
|
-
left: getReactIdentifier(),
|
|
2189
|
+
left: getReactIdentifier(hasReactImport),
|
|
1992
2190
|
right: {
|
|
1993
2191
|
type: 'Identifier',
|
|
1994
2192
|
name: `ElementRef`,
|
|
@@ -2008,7 +2206,7 @@ const getTransforms = (
|
|
|
2008
2206
|
type: 'TSTypeReference',
|
|
2009
2207
|
typeName: {
|
|
2010
2208
|
type: 'TSQualifiedName',
|
|
2011
|
-
left: getReactIdentifier(),
|
|
2209
|
+
left: getReactIdentifier(hasReactImport),
|
|
2012
2210
|
right: {
|
|
2013
2211
|
type: 'Identifier',
|
|
2014
2212
|
name: `Fragment`,
|
|
@@ -2043,7 +2241,7 @@ const getTransforms = (
|
|
|
2043
2241
|
type: 'TSTypeReference',
|
|
2044
2242
|
typeName: {
|
|
2045
2243
|
type: 'TSQualifiedName',
|
|
2046
|
-
left: getReactIdentifier(),
|
|
2244
|
+
left: getReactIdentifier(hasReactImport),
|
|
2047
2245
|
right: {
|
|
2048
2246
|
type: 'Identifier',
|
|
2049
2247
|
name: 'ComponentType',
|
|
@@ -2115,7 +2313,7 @@ const getTransforms = (
|
|
|
2115
2313
|
type: 'TSTypeReference',
|
|
2116
2314
|
typeName: {
|
|
2117
2315
|
type: 'TSQualifiedName',
|
|
2118
|
-
left: getReactIdentifier(),
|
|
2316
|
+
left: getReactIdentifier(hasReactImport),
|
|
2119
2317
|
right: {
|
|
2120
2318
|
type: 'Identifier',
|
|
2121
2319
|
name: 'ComponentType',
|
|
@@ -2135,7 +2333,7 @@ const getTransforms = (
|
|
|
2135
2333
|
type: 'TSTypeReference',
|
|
2136
2334
|
typeName: {
|
|
2137
2335
|
type: 'TSQualifiedName',
|
|
2138
|
-
left: getReactIdentifier(),
|
|
2336
|
+
left: getReactIdentifier(hasReactImport),
|
|
2139
2337
|
right: {
|
|
2140
2338
|
type: 'Identifier',
|
|
2141
2339
|
name: 'ComponentProps',
|
|
@@ -2173,7 +2371,7 @@ const getTransforms = (
|
|
|
2173
2371
|
type: 'TSTypeReference',
|
|
2174
2372
|
typeName: {
|
|
2175
2373
|
type: 'TSQualifiedName',
|
|
2176
|
-
left: getReactIdentifier(),
|
|
2374
|
+
left: getReactIdentifier(hasReactImport),
|
|
2177
2375
|
right: {
|
|
2178
2376
|
type: 'Identifier',
|
|
2179
2377
|
name: `ComponentProps`,
|
|
@@ -2208,7 +2406,7 @@ const getTransforms = (
|
|
|
2208
2406
|
type: 'TSTypeReference',
|
|
2209
2407
|
typeName: {
|
|
2210
2408
|
type: 'TSQualifiedName',
|
|
2211
|
-
left: getReactIdentifier(),
|
|
2409
|
+
left: getReactIdentifier(hasReactImport),
|
|
2212
2410
|
right: {
|
|
2213
2411
|
type: 'Identifier',
|
|
2214
2412
|
name: 'Ref',
|
|
@@ -2492,7 +2690,36 @@ const getTransforms = (
|
|
|
2492
2690
|
):
|
|
2493
2691
|
| TSESTree.TSTypeLiteral
|
|
2494
2692
|
| TSESTree.TSIntersectionType
|
|
2495
|
-
| TSESTree.TSAnyKeyword
|
|
2693
|
+
| TSESTree.TSAnyKeyword
|
|
2694
|
+
| TSESTree.TSMappedType {
|
|
2695
|
+
if (
|
|
2696
|
+
node.properties.length === 1 &&
|
|
2697
|
+
node.properties[0].type === 'ObjectTypeMappedTypeProperty'
|
|
2698
|
+
) {
|
|
2699
|
+
// Mapped Object Object types must not have other object properties.
|
|
2700
|
+
const prop: FlowESTree.ObjectTypeMappedTypeProperty =
|
|
2701
|
+
node.properties[0];
|
|
2702
|
+
const tsProp: TSESTree.TSMappedType = {
|
|
2703
|
+
type: 'TSMappedType',
|
|
2704
|
+
typeParameter: {
|
|
2705
|
+
type: 'TSTypeParameter',
|
|
2706
|
+
name: {
|
|
2707
|
+
type: 'Identifier',
|
|
2708
|
+
name: prop.keyTparam.name,
|
|
2709
|
+
},
|
|
2710
|
+
constraint: transformTypeAnnotationType(prop.sourceType),
|
|
2711
|
+
in: false,
|
|
2712
|
+
out: false,
|
|
2713
|
+
},
|
|
2714
|
+
readonly: prop.variance?.kind === 'plus',
|
|
2715
|
+
optional: prop.optional === 'Optional',
|
|
2716
|
+
typeAnnotation: transformTypeAnnotationType(prop.propType),
|
|
2717
|
+
nameType: null,
|
|
2718
|
+
};
|
|
2719
|
+
|
|
2720
|
+
return tsProp;
|
|
2721
|
+
}
|
|
2722
|
+
|
|
2496
2723
|
// we want to preserve the source order of the members
|
|
2497
2724
|
// unfortunately flow has unordered properties storing things
|
|
2498
2725
|
// so store all elements with their start index and sort the
|
|
@@ -2531,10 +2758,9 @@ const getTransforms = (
|
|
|
2531
2758
|
}
|
|
2532
2759
|
|
|
2533
2760
|
if (property.type === 'ObjectTypeMappedTypeProperty') {
|
|
2534
|
-
// TODO - Support mapped types
|
|
2535
2761
|
return unsupportedAnnotation(
|
|
2536
2762
|
property,
|
|
2537
|
-
'object type with mapped type property',
|
|
2763
|
+
'object type with mapped type property along with other properties',
|
|
2538
2764
|
);
|
|
2539
2765
|
}
|
|
2540
2766
|
|
|
@@ -3063,6 +3289,102 @@ const getTransforms = (
|
|
|
3063
3289
|
type: 'TSVoidKeyword',
|
|
3064
3290
|
};
|
|
3065
3291
|
},
|
|
3292
|
+
ConditionalTypeAnnotation(
|
|
3293
|
+
node: FlowESTree.ConditionalTypeAnnotation,
|
|
3294
|
+
): TSESTree.TSConditionalType {
|
|
3295
|
+
return {
|
|
3296
|
+
type: 'TSConditionalType',
|
|
3297
|
+
checkType: transformTypeAnnotationType(node.checkType),
|
|
3298
|
+
extendsType: transformTypeAnnotationType(node.extendsType),
|
|
3299
|
+
trueType: transformTypeAnnotationType(node.trueType),
|
|
3300
|
+
falseType: transformTypeAnnotationType(node.falseType),
|
|
3301
|
+
};
|
|
3302
|
+
},
|
|
3303
|
+
TypePredicateAnnotation(
|
|
3304
|
+
node: FlowESTree.TypePredicate,
|
|
3305
|
+
): TSESTree.TSTypePredicate {
|
|
3306
|
+
return {
|
|
3307
|
+
type: 'TSTypePredicate',
|
|
3308
|
+
asserts: node.asserts,
|
|
3309
|
+
parameterName: transform.Identifier(node.parameterName, false),
|
|
3310
|
+
typeAnnotation: node.typeAnnotation && {
|
|
3311
|
+
type: 'TSTypeAnnotation',
|
|
3312
|
+
typeAnnotation: transformTypeAnnotationType(node.typeAnnotation),
|
|
3313
|
+
},
|
|
3314
|
+
};
|
|
3315
|
+
},
|
|
3316
|
+
InferTypeAnnotation(
|
|
3317
|
+
node: FlowESTree.InferTypeAnnotation,
|
|
3318
|
+
): TSESTree.TSInferType {
|
|
3319
|
+
return {
|
|
3320
|
+
type: 'TSInferType',
|
|
3321
|
+
typeParameter: transform.TypeParameter(node.typeParameter),
|
|
3322
|
+
};
|
|
3323
|
+
},
|
|
3324
|
+
KeyofTypeAnnotation(
|
|
3325
|
+
node: FlowESTree.KeyofTypeAnnotation,
|
|
3326
|
+
): TSESTree.TSTypeOperator {
|
|
3327
|
+
return {
|
|
3328
|
+
type: 'TSTypeOperator',
|
|
3329
|
+
operator: 'keyof',
|
|
3330
|
+
typeAnnotation: transformTypeAnnotationType(node.argument),
|
|
3331
|
+
};
|
|
3332
|
+
},
|
|
3333
|
+
TypeOperator(node: FlowESTree.TypeOperator): TSESTree.TypeNode {
|
|
3334
|
+
switch (node.operator) {
|
|
3335
|
+
case 'renders': {
|
|
3336
|
+
const hasReactImport = isReactImport(node, 'React');
|
|
3337
|
+
return {
|
|
3338
|
+
type: 'TSTypeReference',
|
|
3339
|
+
typeName: {
|
|
3340
|
+
type: 'TSQualifiedName',
|
|
3341
|
+
left: getReactIdentifier(hasReactImport),
|
|
3342
|
+
right: {
|
|
3343
|
+
type: 'Identifier',
|
|
3344
|
+
name: `ReactNode`,
|
|
3345
|
+
},
|
|
3346
|
+
},
|
|
3347
|
+
typeParameters: undefined,
|
|
3348
|
+
};
|
|
3349
|
+
}
|
|
3350
|
+
}
|
|
3351
|
+
},
|
|
3352
|
+
ComponentTypeAnnotation(
|
|
3353
|
+
node: FlowESTree.ComponentTypeAnnotation,
|
|
3354
|
+
): TSESTree.TSFunctionType {
|
|
3355
|
+
const typeParameters =
|
|
3356
|
+
node.typeParameters == null
|
|
3357
|
+
? undefined
|
|
3358
|
+
: transform.TypeParameterDeclaration(node.typeParameters);
|
|
3359
|
+
|
|
3360
|
+
const params = transform.ComponentTypeParameters(node.params, node.rest);
|
|
3361
|
+
|
|
3362
|
+
// TS cannot support `renderType` so we always use ReactNode as the return type.
|
|
3363
|
+
const hasReactImport = isReactImport(node, 'React');
|
|
3364
|
+
const returnType = {
|
|
3365
|
+
type: 'TSTypeAnnotation',
|
|
3366
|
+
// If no rendersType we assume its ReactNode type.
|
|
3367
|
+
typeAnnotation: {
|
|
3368
|
+
type: 'TSTypeReference',
|
|
3369
|
+
typeName: {
|
|
3370
|
+
type: 'TSQualifiedName',
|
|
3371
|
+
left: getReactIdentifier(hasReactImport),
|
|
3372
|
+
right: {
|
|
3373
|
+
type: 'Identifier',
|
|
3374
|
+
name: `ReactNode`,
|
|
3375
|
+
},
|
|
3376
|
+
},
|
|
3377
|
+
typeParameters: undefined,
|
|
3378
|
+
},
|
|
3379
|
+
};
|
|
3380
|
+
|
|
3381
|
+
return {
|
|
3382
|
+
type: 'TSFunctionType',
|
|
3383
|
+
typeParameters,
|
|
3384
|
+
params,
|
|
3385
|
+
returnType,
|
|
3386
|
+
};
|
|
3387
|
+
},
|
|
3066
3388
|
};
|
|
3067
3389
|
|
|
3068
3390
|
// wrap each transform so that we automatically preserve jsdoc comments
|