flow-api-translator 0.36.1 → 0.327.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/TSDefToFlowDef.js +66 -327
- package/dist/TSDefToFlowDef.js.flow +70 -35
- package/dist/flowDefToTSDef.js +134 -825
- package/dist/flowDefToTSDef.js.flow +196 -100
- package/dist/flowImportTo.js +5 -25
- package/dist/flowImportTo.js.flow +4 -4
- package/dist/flowToFlowDef.js +190 -379
- package/dist/flowToFlowDef.js.flow +109 -27
- package/dist/flowToJS.js +3 -19
- package/dist/flowToJS.js.flow +5 -5
- package/dist/index.js +12 -50
- package/dist/index.js.flow +1 -1
- package/dist/src/TSDefToFlowDef.js +66 -327
- package/dist/src/flowDefToTSDef.js +134 -825
- package/dist/src/flowImportTo.js +5 -25
- package/dist/src/flowToFlowDef.js +190 -379
- package/dist/src/flowToJS.js +3 -19
- package/dist/src/index.js +12 -50
- package/dist/src/utils/DocblockUtils.js +4 -14
- package/dist/src/utils/ErrorUtils.js +4 -40
- package/dist/src/utils/FlowAnalyze.js +8 -28
- package/dist/src/utils/TSNodeUtils.js +83 -0
- package/dist/src/utils/TranslationUtils.js +0 -13
- package/dist/src/utils/ts-estree-ast-types.js +0 -29
- package/dist/utils/DocblockUtils.js +4 -14
- package/dist/utils/DocblockUtils.js.flow +1 -1
- package/dist/utils/ErrorUtils.js +4 -40
- package/dist/utils/ErrorUtils.js.flow +6 -6
- package/dist/utils/FlowAnalyze.js +8 -28
- package/dist/utils/FlowAnalyze.js.flow +9 -4
- package/dist/utils/TSNodeUtils.js +83 -0
- package/dist/utils/TSNodeUtils.js.flow +108 -0
- package/dist/utils/TranslationUtils.js +0 -13
- package/dist/utils/TranslationUtils.js.flow +2 -2
- package/dist/utils/ts-estree-ast-types.js +0 -29
- package/dist/utils/ts-estree-ast-types.js.flow +697 -740
- package/package.json +10 -9
package/dist/flowDefToTSDef.js
CHANGED
|
@@ -1,35 +1,17 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
3
|
-
*
|
|
4
|
-
* This source code is licensed under the MIT license found in the
|
|
5
|
-
* LICENSE file in the root directory of this source tree.
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* @format
|
|
9
|
-
*/
|
|
10
1
|
'use strict';
|
|
11
2
|
|
|
12
3
|
Object.defineProperty(exports, "__esModule", {
|
|
13
4
|
value: true
|
|
14
5
|
});
|
|
15
6
|
exports.flowDefToTSDef = flowDefToTSDef;
|
|
16
|
-
|
|
17
|
-
var FlowESTree = _interopRequireWildcard(require("hermes-estree"));
|
|
18
|
-
|
|
7
|
+
var FlowESTree = _interopRequireWildcard(require("flow-estree"));
|
|
19
8
|
var TSESTree = _interopRequireWildcard(require("./utils/ts-estree-ast-types"));
|
|
20
|
-
|
|
21
|
-
var _hermesTransform = require("hermes-transform");
|
|
22
|
-
|
|
9
|
+
var _flowTransform = require("flow-transform");
|
|
23
10
|
var _ErrorUtils = require("./utils/ErrorUtils");
|
|
24
|
-
|
|
25
11
|
var _DocblockUtils = require("./utils/DocblockUtils");
|
|
26
|
-
|
|
12
|
+
var _TSNodeUtils = require("./utils/TSNodeUtils");
|
|
27
13
|
var _os = require("os");
|
|
28
|
-
|
|
29
|
-
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
|
30
|
-
|
|
31
|
-
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
|
32
|
-
|
|
14
|
+
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
|
|
33
15
|
const DUMMY_LOC = {
|
|
34
16
|
start: {
|
|
35
17
|
line: 1,
|
|
@@ -40,36 +22,57 @@ const DUMMY_LOC = {
|
|
|
40
22
|
column: 0
|
|
41
23
|
}
|
|
42
24
|
};
|
|
43
|
-
|
|
44
25
|
function constructFlowNode(node) {
|
|
45
26
|
return node;
|
|
46
27
|
}
|
|
47
|
-
|
|
48
|
-
const
|
|
49
|
-
|
|
50
|
-
const
|
|
51
|
-
|
|
28
|
+
const cloneJSDocCommentsToNewNode = _flowTransform.cloneJSDocCommentsToNewNode;
|
|
29
|
+
const makeCommentOwnLine = _flowTransform.makeCommentOwnLine;
|
|
30
|
+
function normalizeDeclareComponentParams(params, rest, onUnexpected) {
|
|
31
|
+
const normalizedParams = [];
|
|
32
|
+
let normalizedRest = rest;
|
|
33
|
+
const toComponentTypeParameter = (name, local, source) => {
|
|
34
|
+
if (local.type !== 'Identifier' || local.typeAnnotation == null) {
|
|
35
|
+
throw onUnexpected(source, `DeclareComponent: expected an annotated identifier parameter, got "${local.type}"`);
|
|
36
|
+
}
|
|
37
|
+
return constructFlowNode({
|
|
38
|
+
type: 'ComponentTypeParameter',
|
|
39
|
+
name,
|
|
40
|
+
typeAnnotation: local.typeAnnotation.typeAnnotation,
|
|
41
|
+
optional: local.optional,
|
|
42
|
+
loc: source.loc,
|
|
43
|
+
range: source.range
|
|
44
|
+
});
|
|
45
|
+
};
|
|
46
|
+
for (const param of params) {
|
|
47
|
+
switch (param.type) {
|
|
48
|
+
case 'ComponentTypeParameter':
|
|
49
|
+
normalizedParams.push(param);
|
|
50
|
+
break;
|
|
51
|
+
case 'ComponentParameter':
|
|
52
|
+
normalizedParams.push(toComponentTypeParameter(param.name, param.local, param));
|
|
53
|
+
break;
|
|
54
|
+
case 'RestElement':
|
|
55
|
+
normalizedRest = toComponentTypeParameter(null, param.argument, param);
|
|
56
|
+
break;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
return [normalizedParams, normalizedRest];
|
|
60
|
+
}
|
|
52
61
|
const VALID_REACT_IMPORTS = new Set(['React', 'react']);
|
|
53
|
-
|
|
54
62
|
function isValidReactImportOrGlobal(id) {
|
|
55
63
|
return VALID_REACT_IMPORTS.has(id.name) || id.name.startsWith('React$');
|
|
56
64
|
}
|
|
57
|
-
|
|
58
|
-
let shouldAddReactImport = null; // Returns appropriate Identifier for `React` import.
|
|
59
|
-
// If a global is in use, set a flag to indicate that we should add the import.
|
|
60
|
-
|
|
65
|
+
let shouldAddReactImport = null;
|
|
61
66
|
function getReactIdentifier(hasReactImport) {
|
|
62
67
|
if (shouldAddReactImport !== false) {
|
|
63
68
|
shouldAddReactImport = !hasReactImport;
|
|
64
69
|
}
|
|
65
|
-
|
|
66
70
|
return {
|
|
67
71
|
type: 'Identifier',
|
|
68
72
|
loc: DUMMY_LOC,
|
|
69
73
|
name: `React`
|
|
70
74
|
};
|
|
71
75
|
}
|
|
72
|
-
|
|
73
76
|
function flowDefToTSDef(originalCode, ast, scopeManager, opts) {
|
|
74
77
|
const tsBody = [];
|
|
75
78
|
const tsProgram = {
|
|
@@ -81,13 +84,9 @@ function flowDefToTSDef(originalCode, ast, scopeManager, opts) {
|
|
|
81
84
|
};
|
|
82
85
|
shouldAddReactImport = null;
|
|
83
86
|
const [transform, code] = getTransforms(originalCode, scopeManager, opts);
|
|
84
|
-
|
|
85
87
|
for (const node of ast.body) {
|
|
86
88
|
if (node.type in transform) {
|
|
87
|
-
const result = transform[
|
|
88
|
-
// $FlowFixMe[incompatible-type]
|
|
89
|
-
node.type]( // $FlowExpectedError[incompatible-type]
|
|
90
|
-
node);
|
|
89
|
+
const result = transform[node.type](node);
|
|
91
90
|
tsBody.push(...(Array.isArray(result) ? result : [result]));
|
|
92
91
|
} else {
|
|
93
92
|
throw (0, _ErrorUtils.unexpectedTranslationError)(node, `Unexpected node type ${node.type}`, {
|
|
@@ -95,7 +94,6 @@ function flowDefToTSDef(originalCode, ast, scopeManager, opts) {
|
|
|
95
94
|
});
|
|
96
95
|
}
|
|
97
96
|
}
|
|
98
|
-
|
|
99
97
|
if (shouldAddReactImport === true) {
|
|
100
98
|
tsBody.unshift({
|
|
101
99
|
type: 'ImportDeclaration',
|
|
@@ -119,36 +117,28 @@ function flowDefToTSDef(originalCode, ast, scopeManager, opts) {
|
|
|
119
117
|
importKind: 'value'
|
|
120
118
|
});
|
|
121
119
|
}
|
|
122
|
-
|
|
123
120
|
return [tsProgram, code];
|
|
124
121
|
}
|
|
125
|
-
|
|
126
122
|
const getTransforms = (originalCode, scopeManager, opts) => {
|
|
127
123
|
let code = originalCode;
|
|
128
|
-
|
|
129
124
|
function translationError(node, message) {
|
|
130
125
|
return (0, _ErrorUtils.translationError)(node, message, {
|
|
131
126
|
code
|
|
132
127
|
});
|
|
133
128
|
}
|
|
134
|
-
|
|
135
129
|
function unexpectedTranslationError(node, message) {
|
|
136
130
|
return (0, _ErrorUtils.unexpectedTranslationError)(node, message, {
|
|
137
131
|
code
|
|
138
132
|
});
|
|
139
133
|
}
|
|
140
|
-
|
|
141
134
|
function unsupportedFeatureMessage(thing) {
|
|
142
135
|
return `Unsupported feature: Translating "${thing}" is currently not supported.`;
|
|
143
136
|
}
|
|
144
|
-
|
|
145
137
|
function buildCodeFrameForComment(node, message) {
|
|
146
138
|
return (0, _ErrorUtils.buildCodeFrame)(node, message, code, false);
|
|
147
139
|
}
|
|
148
|
-
|
|
149
140
|
function addErrorComment(node, message) {
|
|
150
141
|
var _node$comments;
|
|
151
|
-
|
|
152
142
|
const comment = {
|
|
153
143
|
type: 'Block',
|
|
154
144
|
loc: DUMMY_LOC,
|
|
@@ -156,17 +146,12 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
156
146
|
leading: true,
|
|
157
147
|
printed: false
|
|
158
148
|
};
|
|
159
|
-
code = makeCommentOwnLine(code, comment);
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
(_node$comments = node.comments) != null ? _node$comments : node.comments = []; // $FlowExpectedError[incompatible-type]
|
|
163
|
-
|
|
149
|
+
code = makeCommentOwnLine(code, comment);
|
|
150
|
+
(_node$comments = node.comments) != null ? _node$comments : node.comments = [];
|
|
164
151
|
node.comments.push(comment);
|
|
165
152
|
}
|
|
166
|
-
|
|
167
153
|
function unsupportedAnnotation(node, thing) {
|
|
168
154
|
const message = unsupportedFeatureMessage(thing);
|
|
169
|
-
|
|
170
155
|
if (opts.recoverFromErrors) {
|
|
171
156
|
const codeFrame = buildCodeFrameForComment(node, message);
|
|
172
157
|
const newNode = {
|
|
@@ -176,13 +161,10 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
176
161
|
addErrorComment(newNode, codeFrame);
|
|
177
162
|
return newNode;
|
|
178
163
|
}
|
|
179
|
-
|
|
180
164
|
throw translationError(node, message);
|
|
181
165
|
}
|
|
182
|
-
|
|
183
166
|
function unsupportedDeclaration(node, thing, id, declare = false, typeParameters = null) {
|
|
184
167
|
const message = unsupportedFeatureMessage(thing);
|
|
185
|
-
|
|
186
168
|
if (opts.recoverFromErrors) {
|
|
187
169
|
const codeFrame = buildCodeFrameForComment(node, message);
|
|
188
170
|
const newNode = {
|
|
@@ -199,37 +181,28 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
199
181
|
addErrorComment(newNode, codeFrame);
|
|
200
182
|
return newNode;
|
|
201
183
|
}
|
|
202
|
-
|
|
203
184
|
throw translationError(node, message);
|
|
204
185
|
}
|
|
205
|
-
|
|
206
186
|
const topScope = (() => {
|
|
207
187
|
const globalScope = scopeManager.globalScope;
|
|
208
|
-
|
|
209
188
|
if (globalScope.childScopes.length > 0 && globalScope.childScopes[0].type === 'module') {
|
|
210
189
|
return globalScope.childScopes[0];
|
|
211
190
|
}
|
|
212
|
-
|
|
213
191
|
return globalScope;
|
|
214
192
|
})();
|
|
215
|
-
|
|
216
193
|
function isReactImport(scopeNode, name) {
|
|
217
194
|
let currentScope = (() => {
|
|
218
195
|
let scope = null;
|
|
219
196
|
let node = scopeNode;
|
|
220
|
-
|
|
221
197
|
while (!scope && node) {
|
|
222
198
|
scope = scopeManager.acquire(node, true);
|
|
223
199
|
node = node.parent;
|
|
224
200
|
}
|
|
225
|
-
|
|
226
201
|
return scope;
|
|
227
202
|
})();
|
|
228
|
-
|
|
229
203
|
if (currentScope == null) {
|
|
230
204
|
throw new Error('unable to resolve scope');
|
|
231
205
|
}
|
|
232
|
-
|
|
233
206
|
const variableDef = (() => {
|
|
234
207
|
while (currentScope != null) {
|
|
235
208
|
for (const variable of currentScope.variables) {
|
|
@@ -237,105 +210,44 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
237
210
|
return variable;
|
|
238
211
|
}
|
|
239
212
|
}
|
|
240
|
-
|
|
241
213
|
currentScope = currentScope.upper;
|
|
242
214
|
}
|
|
243
|
-
})();
|
|
244
|
-
// It could be a global though if isValidReactImportOrGlobal returns true.
|
|
245
|
-
|
|
246
|
-
|
|
215
|
+
})();
|
|
247
216
|
if (variableDef == null) {
|
|
248
217
|
return false;
|
|
249
218
|
}
|
|
250
|
-
|
|
251
|
-
const def = variableDef.defs[0]; // Detect:
|
|
252
|
-
|
|
219
|
+
const def = variableDef.defs[0];
|
|
253
220
|
switch (def.type) {
|
|
254
|
-
// import React from 'react';
|
|
255
|
-
// import * as React from 'react';
|
|
256
221
|
case 'ImportBinding':
|
|
257
222
|
{
|
|
258
223
|
if (def.node.type === 'ImportDefaultSpecifier' || def.node.type === 'ImportNamespaceSpecifier') {
|
|
259
224
|
return VALID_REACT_IMPORTS.has(def.parent.source.value);
|
|
260
225
|
}
|
|
261
|
-
|
|
262
226
|
return false;
|
|
263
227
|
}
|
|
264
|
-
// Globals
|
|
265
|
-
|
|
266
228
|
case 'ImplicitGlobalVariable':
|
|
267
229
|
{
|
|
268
230
|
return VALID_REACT_IMPORTS.has(name);
|
|
269
231
|
}
|
|
270
|
-
// TODO Handle:
|
|
271
|
-
// const React = require('react');
|
|
272
|
-
// const Something = React;
|
|
273
232
|
}
|
|
274
|
-
|
|
275
233
|
return false;
|
|
276
234
|
}
|
|
277
|
-
|
|
278
235
|
function EnumImpl(node) {
|
|
279
236
|
const body = node.body;
|
|
280
|
-
|
|
281
237
|
if (body.type === 'EnumSymbolBody') {
|
|
282
|
-
/*
|
|
283
|
-
There's unfortunately no way for us to support this in a clean way.
|
|
284
|
-
We can get really close using this code:
|
|
285
|
-
```
|
|
286
|
-
declare namespace SymbolEnum {
|
|
287
|
-
export const member1: unique symbol;
|
|
288
|
-
export type member1 = typeof member1;
|
|
289
|
-
export const member2: unique symbol;
|
|
290
|
-
export type member2 = typeof member2;
|
|
291
|
-
}
|
|
292
|
-
type SymbolEnum = typeof SymbolEnum[keyof typeof SymbolEnum];
|
|
293
|
-
```
|
|
294
|
-
However as explained in https://github.com/microsoft/TypeScript/issues/43657:
|
|
295
|
-
"A unique symbol type is never transferred from one declaration to another through inference."
|
|
296
|
-
This intended behaviour in TS means that the usage of the fake-enum would look like this:
|
|
297
|
-
```
|
|
298
|
-
const value: SymbolEnum.member1 = SymbolEnum.member1;
|
|
299
|
-
// ^^^^^^^^^^^^^^^^^^ required to force TS to retain the information
|
|
300
|
-
```
|
|
301
|
-
Which is really clunky and shitty. It definitely works, but ofc it's not good.
|
|
302
|
-
We can go with this design if users are okay with it!
|
|
303
|
-
Considering how rarely used symbol enums are ATM, let's just put a pin in it for now.
|
|
304
|
-
*/
|
|
305
238
|
return unsupportedDeclaration(node, 'symbol enums', node.id, FlowESTree.isDeclareEnum(node));
|
|
306
239
|
}
|
|
307
|
-
|
|
308
240
|
if (body.type === 'EnumBooleanBody') {
|
|
309
|
-
/*
|
|
310
|
-
TODO - TS enums only allow strings or numbers as their values - not booleans.
|
|
311
|
-
This means we need a non-ts-enum representation of the enum.
|
|
312
|
-
We can support boolean enums using a construct like this:
|
|
313
|
-
```ts
|
|
314
|
-
declare namespace BooleanEnum {
|
|
315
|
-
export const member1: true;
|
|
316
|
-
export type member1 = typeof member1;
|
|
317
|
-
export const member2: false;
|
|
318
|
-
export type member2 = typeof member1;
|
|
319
|
-
}
|
|
320
|
-
declare type BooleanEnum = boolean;
|
|
321
|
-
```
|
|
322
|
-
But it's pretty clunky and ugly.
|
|
323
|
-
Considering how rarely used boolean enums are ATM, let's just put a pin in it for now.
|
|
324
|
-
*/
|
|
325
241
|
return unsupportedDeclaration(node, 'boolean enums', node.id, FlowESTree.isDeclareEnum(node));
|
|
326
242
|
}
|
|
327
|
-
|
|
328
243
|
const members = [];
|
|
329
|
-
|
|
330
244
|
for (const member of body.members) {
|
|
331
245
|
switch (member.type) {
|
|
332
246
|
case 'EnumDefaultedMember':
|
|
333
247
|
{
|
|
334
248
|
if (body.type === 'EnumNumberBody') {
|
|
335
|
-
// this should be impossible!
|
|
336
249
|
throw unexpectedTranslationError(member, 'Unexpected defaulted number enum member');
|
|
337
250
|
}
|
|
338
|
-
|
|
339
251
|
members.push({
|
|
340
252
|
type: 'TSEnumMember',
|
|
341
253
|
loc: DUMMY_LOC,
|
|
@@ -350,7 +262,6 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
350
262
|
});
|
|
351
263
|
break;
|
|
352
264
|
}
|
|
353
|
-
|
|
354
265
|
case 'EnumNumberMember':
|
|
355
266
|
case 'EnumStringMember':
|
|
356
267
|
members.push({
|
|
@@ -362,7 +273,6 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
362
273
|
});
|
|
363
274
|
}
|
|
364
275
|
}
|
|
365
|
-
|
|
366
276
|
const bodyRepresentationType = body.type === 'EnumNumberBody' ? {
|
|
367
277
|
type: 'TSNumberKeyword',
|
|
368
278
|
loc: DUMMY_LOC
|
|
@@ -383,22 +293,7 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
383
293
|
loc: DUMMY_LOC
|
|
384
294
|
},
|
|
385
295
|
members
|
|
386
|
-
},
|
|
387
|
-
// we can use declaration merging to declare these functions on the enum:
|
|
388
|
-
|
|
389
|
-
/*
|
|
390
|
-
declare enum Foo {
|
|
391
|
-
A = 1,
|
|
392
|
-
B = 2,
|
|
393
|
-
}
|
|
394
|
-
declare namespace Foo {
|
|
395
|
-
export function cast(value: number | null | undefined): Foo;
|
|
396
|
-
export function isValid(value: number | null | undefined): value is Foo;
|
|
397
|
-
export function members(): IterableIterator<Foo>;
|
|
398
|
-
export function getName(value: Foo): string;
|
|
399
|
-
}
|
|
400
|
-
*/
|
|
401
|
-
{
|
|
296
|
+
}, {
|
|
402
297
|
type: 'TSModuleDeclaration',
|
|
403
298
|
loc: DUMMY_LOC,
|
|
404
299
|
declare: true,
|
|
@@ -407,8 +302,7 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
407
302
|
body: {
|
|
408
303
|
type: 'TSModuleBlock',
|
|
409
304
|
loc: DUMMY_LOC,
|
|
410
|
-
body: [
|
|
411
|
-
{
|
|
305
|
+
body: [{
|
|
412
306
|
type: 'ExportNamedDeclaration',
|
|
413
307
|
loc: DUMMY_LOC,
|
|
414
308
|
declaration: {
|
|
@@ -456,8 +350,7 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
456
350
|
source: null,
|
|
457
351
|
exportKind: 'value',
|
|
458
352
|
assertions: []
|
|
459
|
-
},
|
|
460
|
-
{
|
|
353
|
+
}, {
|
|
461
354
|
type: 'ExportNamedDeclaration',
|
|
462
355
|
loc: DUMMY_LOC,
|
|
463
356
|
declaration: {
|
|
@@ -519,8 +412,7 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
519
412
|
source: null,
|
|
520
413
|
exportKind: 'value',
|
|
521
414
|
assertions: []
|
|
522
|
-
},
|
|
523
|
-
{
|
|
415
|
+
}, {
|
|
524
416
|
type: 'ExportNamedDeclaration',
|
|
525
417
|
loc: DUMMY_LOC,
|
|
526
418
|
declaration: {
|
|
@@ -546,7 +438,7 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
546
438
|
loc: DUMMY_LOC,
|
|
547
439
|
name: 'IterableIterator'
|
|
548
440
|
},
|
|
549
|
-
|
|
441
|
+
typeArguments: {
|
|
550
442
|
type: 'TSTypeParameterInstantiation',
|
|
551
443
|
loc: DUMMY_LOC,
|
|
552
444
|
params: [{
|
|
@@ -562,8 +454,7 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
562
454
|
source: null,
|
|
563
455
|
exportKind: 'value',
|
|
564
456
|
assertions: []
|
|
565
|
-
},
|
|
566
|
-
{
|
|
457
|
+
}, {
|
|
567
458
|
type: 'ExportNamedDeclaration',
|
|
568
459
|
loc: DUMMY_LOC,
|
|
569
460
|
declaration: {
|
|
@@ -608,133 +499,92 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
608
499
|
}
|
|
609
500
|
}];
|
|
610
501
|
}
|
|
611
|
-
|
|
612
502
|
const getPlaceholderNameForTypeofImport = (() => {
|
|
613
503
|
let typeof_import_count = 0;
|
|
614
504
|
return () => `$$IMPORT_TYPEOF_${++typeof_import_count}$$`;
|
|
615
505
|
})();
|
|
616
|
-
|
|
617
506
|
const transformTypeAnnotationType = node => {
|
|
618
507
|
switch (node.type) {
|
|
619
508
|
case 'AnyTypeAnnotation':
|
|
620
509
|
return transform.AnyTypeAnnotation(node);
|
|
621
|
-
|
|
622
510
|
case 'ArrayTypeAnnotation':
|
|
623
511
|
return transform.ArrayTypeAnnotation(node);
|
|
624
|
-
|
|
625
512
|
case 'BigIntLiteralTypeAnnotation':
|
|
626
513
|
return transform.BigIntLiteralTypeAnnotation(node);
|
|
627
|
-
|
|
628
514
|
case 'BigIntTypeAnnotation':
|
|
629
515
|
return transform.BigIntTypeAnnotation(node);
|
|
630
|
-
|
|
631
516
|
case 'BooleanLiteralTypeAnnotation':
|
|
632
517
|
return transform.BooleanLiteralTypeAnnotation(node);
|
|
633
|
-
|
|
634
518
|
case 'BooleanTypeAnnotation':
|
|
635
519
|
return transform.BooleanTypeAnnotation(node);
|
|
636
|
-
|
|
637
520
|
case 'EmptyTypeAnnotation':
|
|
638
521
|
return transform.EmptyTypeAnnotation(node);
|
|
639
|
-
|
|
640
522
|
case 'ExistsTypeAnnotation':
|
|
641
523
|
return transform.ExistsTypeAnnotation(node);
|
|
642
|
-
|
|
643
524
|
case 'FunctionTypeAnnotation':
|
|
644
525
|
return transform.FunctionTypeAnnotation(node);
|
|
645
|
-
|
|
646
526
|
case 'GenericTypeAnnotation':
|
|
647
527
|
return transform.GenericTypeAnnotation(node);
|
|
648
|
-
|
|
649
528
|
case 'IndexedAccessType':
|
|
650
529
|
return transform.IndexedAccessType(node);
|
|
651
|
-
|
|
652
530
|
case 'InterfaceTypeAnnotation':
|
|
653
531
|
return transform.InterfaceTypeAnnotation(node);
|
|
654
|
-
|
|
655
532
|
case 'IntersectionTypeAnnotation':
|
|
656
533
|
return transform.IntersectionTypeAnnotation(node);
|
|
657
|
-
|
|
658
534
|
case 'MixedTypeAnnotation':
|
|
659
535
|
return transform.MixedTypeAnnotation(node);
|
|
660
|
-
|
|
661
536
|
case 'NullLiteralTypeAnnotation':
|
|
662
537
|
return transform.NullLiteralTypeAnnotation(node);
|
|
663
|
-
|
|
664
538
|
case 'NullableTypeAnnotation':
|
|
665
539
|
return transform.NullableTypeAnnotation(node);
|
|
666
|
-
|
|
667
540
|
case 'NumberLiteralTypeAnnotation':
|
|
668
541
|
return transform.NumberLiteralTypeAnnotation(node);
|
|
669
|
-
|
|
670
542
|
case 'NumberTypeAnnotation':
|
|
671
543
|
return transform.NumberTypeAnnotation(node);
|
|
672
|
-
|
|
673
544
|
case 'ObjectTypeAnnotation':
|
|
674
545
|
return transform.ObjectTypeAnnotation(node);
|
|
675
|
-
|
|
676
546
|
case 'OptionalIndexedAccessType':
|
|
677
547
|
return transform.OptionalIndexedAccessType(node);
|
|
678
|
-
|
|
679
548
|
case 'QualifiedTypeIdentifier':
|
|
680
549
|
return transform.QualifiedTypeIdentifier(node);
|
|
681
|
-
|
|
682
550
|
case 'StringLiteralTypeAnnotation':
|
|
683
551
|
return transform.StringLiteralTypeAnnotation(node);
|
|
684
|
-
|
|
685
552
|
case 'StringTypeAnnotation':
|
|
686
553
|
return transform.StringTypeAnnotation(node);
|
|
687
|
-
|
|
688
554
|
case 'SymbolTypeAnnotation':
|
|
689
555
|
return transform.SymbolTypeAnnotation(node);
|
|
690
|
-
|
|
691
556
|
case 'ThisTypeAnnotation':
|
|
692
557
|
return transform.ThisTypeAnnotation(node);
|
|
693
|
-
|
|
694
558
|
case 'TupleTypeAnnotation':
|
|
695
559
|
return transform.TupleTypeAnnotation(node);
|
|
696
|
-
|
|
697
560
|
case 'TypeofTypeAnnotation':
|
|
698
561
|
return transform.TypeofTypeAnnotation(node);
|
|
699
|
-
|
|
700
562
|
case 'UnionTypeAnnotation':
|
|
701
563
|
return transform.UnionTypeAnnotation(node);
|
|
702
|
-
|
|
703
564
|
case 'VoidTypeAnnotation':
|
|
704
565
|
return transform.VoidTypeAnnotation(node);
|
|
705
|
-
|
|
706
566
|
case 'TypePredicate':
|
|
707
567
|
return transform.TypePredicateAnnotation(node);
|
|
708
|
-
|
|
709
568
|
case 'ConditionalTypeAnnotation':
|
|
710
569
|
return transform.ConditionalTypeAnnotation(node);
|
|
711
|
-
|
|
712
570
|
case 'InferTypeAnnotation':
|
|
713
571
|
return transform.InferTypeAnnotation(node);
|
|
714
|
-
|
|
715
572
|
case 'KeyofTypeAnnotation':
|
|
716
573
|
return transform.KeyofTypeAnnotation(node);
|
|
717
|
-
|
|
718
574
|
case 'TypeOperator':
|
|
719
575
|
return transform.TypeOperator(node);
|
|
720
|
-
|
|
721
576
|
case 'ComponentTypeAnnotation':
|
|
722
577
|
return transform.ComponentTypeAnnotation(node);
|
|
723
|
-
|
|
724
578
|
case 'NeverTypeAnnotation':
|
|
725
579
|
return transform.NeverTypeAnnotation(node);
|
|
726
|
-
|
|
727
580
|
case 'UndefinedTypeAnnotation':
|
|
728
581
|
return transform.UndefinedTypeAnnotation(node);
|
|
729
|
-
|
|
730
582
|
case 'UnknownTypeAnnotation':
|
|
731
583
|
return transform.UnknownTypeAnnotation(node);
|
|
732
|
-
|
|
733
584
|
default:
|
|
734
585
|
throw unexpectedTranslationError(node, `Unhandled type ${node.type}`);
|
|
735
586
|
}
|
|
736
587
|
};
|
|
737
|
-
|
|
738
588
|
const wellKnownSymbols = new Set(['iterator', 'asyncIterator', 'dispose', 'asyncDispose']);
|
|
739
589
|
const transform = {
|
|
740
590
|
AnyTypeAnnotation(_node) {
|
|
@@ -743,7 +593,6 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
743
593
|
loc: DUMMY_LOC
|
|
744
594
|
};
|
|
745
595
|
},
|
|
746
|
-
|
|
747
596
|
ArrayTypeAnnotation(node) {
|
|
748
597
|
return {
|
|
749
598
|
type: 'TSArrayType',
|
|
@@ -751,7 +600,6 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
751
600
|
elementType: transformTypeAnnotationType(node.elementType)
|
|
752
601
|
};
|
|
753
602
|
},
|
|
754
|
-
|
|
755
603
|
BigIntLiteral(node) {
|
|
756
604
|
return {
|
|
757
605
|
type: 'Literal',
|
|
@@ -761,17 +609,9 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
761
609
|
value: node.value
|
|
762
610
|
};
|
|
763
611
|
},
|
|
764
|
-
|
|
765
612
|
BigIntLiteralTypeAnnotation(node) {
|
|
766
613
|
var _node$bigint;
|
|
767
|
-
|
|
768
|
-
// technically hermes doesn't support this yet
|
|
769
|
-
// but future proofing amirite
|
|
770
|
-
const bigint = // $FlowExpectedError[prop-missing]
|
|
771
|
-
(_node$bigint = node.bigint) != null ? _node$bigint : node.raw // estree spec is to not have a trailing `n` on this property
|
|
772
|
-
// https://github.com/estree/estree/blob/db962bb417a97effcfe9892f87fbb93c81a68584/es2020.md#bigintliteral
|
|
773
|
-
.replace(/n$/, '') // `BigInt` doesn't accept numeric separator and `bigint` property should not include numeric separator
|
|
774
|
-
.replace(/_/, '');
|
|
614
|
+
const bigint = (_node$bigint = node.bigint) != null ? _node$bigint : node.raw.replace(/n$/, '').replace(/_/, '');
|
|
775
615
|
return {
|
|
776
616
|
type: 'TSLiteralType',
|
|
777
617
|
loc: DUMMY_LOC,
|
|
@@ -784,14 +624,12 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
784
624
|
}
|
|
785
625
|
};
|
|
786
626
|
},
|
|
787
|
-
|
|
788
627
|
BigIntTypeAnnotation(_node) {
|
|
789
628
|
return {
|
|
790
629
|
type: 'TSBigIntKeyword',
|
|
791
630
|
loc: DUMMY_LOC
|
|
792
631
|
};
|
|
793
632
|
},
|
|
794
|
-
|
|
795
633
|
BooleanLiteral(node) {
|
|
796
634
|
return {
|
|
797
635
|
type: 'Literal',
|
|
@@ -800,7 +638,6 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
800
638
|
value: node.value
|
|
801
639
|
};
|
|
802
640
|
},
|
|
803
|
-
|
|
804
641
|
BooleanLiteralTypeAnnotation(node) {
|
|
805
642
|
return {
|
|
806
643
|
type: 'TSLiteralType',
|
|
@@ -813,53 +650,41 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
813
650
|
}
|
|
814
651
|
};
|
|
815
652
|
},
|
|
816
|
-
|
|
817
653
|
BooleanTypeAnnotation(_node) {
|
|
818
654
|
return {
|
|
819
655
|
type: 'TSBooleanKeyword',
|
|
820
656
|
loc: DUMMY_LOC
|
|
821
657
|
};
|
|
822
658
|
},
|
|
823
|
-
|
|
824
659
|
ClassImplements(node) {
|
|
825
660
|
return {
|
|
826
661
|
type: 'TSClassImplements',
|
|
827
662
|
loc: DUMMY_LOC,
|
|
828
663
|
expression: transform.Identifier(node.id, false),
|
|
829
|
-
|
|
664
|
+
typeArguments: transform.TypeParameterInstantiation(node.typeParameters)
|
|
830
665
|
};
|
|
831
666
|
},
|
|
832
|
-
|
|
833
667
|
DeclareClass(node) {
|
|
834
668
|
const classMembers = [];
|
|
835
669
|
const transformedBody = transform.ObjectTypeAnnotation(node.body);
|
|
836
|
-
|
|
837
670
|
if (transformedBody.type !== 'TSTypeLiteral') {
|
|
838
671
|
return unsupportedDeclaration(node.body, 'Spreads in declare class are not allowed', node.id, true, node.typeParameters);
|
|
839
672
|
}
|
|
840
|
-
|
|
841
673
|
for (const member of transformedBody.members) {
|
|
842
|
-
// TS uses the real ClassDeclaration AST so we need to
|
|
843
|
-
// make the signatures real methods/properties
|
|
844
674
|
switch (member.type) {
|
|
845
675
|
case 'TSIndexSignature':
|
|
846
676
|
{
|
|
847
677
|
classMembers.push(member);
|
|
848
678
|
break;
|
|
849
679
|
}
|
|
850
|
-
|
|
851
680
|
case 'TSMethodSignature':
|
|
852
681
|
{
|
|
853
|
-
// flow just creates a method signature like any other for a constructor
|
|
854
|
-
// but the proper AST has `kind = 'constructor'`
|
|
855
682
|
const isConstructor = (() => {
|
|
856
683
|
if (member.computed === true) {
|
|
857
684
|
return false;
|
|
858
685
|
}
|
|
859
|
-
|
|
860
686
|
return member.key.type === 'Identifier' && member.key.name === 'constructor' || member.key.type === 'Literal' && member.key.value === 'constructor';
|
|
861
687
|
})();
|
|
862
|
-
|
|
863
688
|
if (isConstructor) {
|
|
864
689
|
const newNode = {
|
|
865
690
|
type: 'MethodDefinition',
|
|
@@ -885,7 +710,6 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
885
710
|
generator: false,
|
|
886
711
|
id: null,
|
|
887
712
|
params: member.params,
|
|
888
|
-
// constructors explicitly have no return type
|
|
889
713
|
returnType: undefined,
|
|
890
714
|
typeParameters: member.typeParameters
|
|
891
715
|
}
|
|
@@ -894,13 +718,10 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
894
718
|
classMembers.push(newNode);
|
|
895
719
|
} else {
|
|
896
720
|
var _member$static;
|
|
897
|
-
|
|
898
721
|
const [key, computed] = (() => {
|
|
899
722
|
const _key = member.key;
|
|
900
|
-
|
|
901
723
|
if (_key.type === 'Identifier' && _key.name.startsWith('@@')) {
|
|
902
724
|
const name = _key.name.slice(2);
|
|
903
|
-
|
|
904
725
|
if (wellKnownSymbols.has(name)) {
|
|
905
726
|
return [{
|
|
906
727
|
type: 'MemberExpression',
|
|
@@ -922,10 +743,8 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
922
743
|
}, true];
|
|
923
744
|
}
|
|
924
745
|
}
|
|
925
|
-
|
|
926
746
|
return [member.key, member.computed];
|
|
927
747
|
})();
|
|
928
|
-
|
|
929
748
|
const newNode = {
|
|
930
749
|
type: 'MethodDefinition',
|
|
931
750
|
loc: DUMMY_LOC,
|
|
@@ -953,14 +772,11 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
953
772
|
cloneJSDocCommentsToNewNode(member, newNode);
|
|
954
773
|
classMembers.push(newNode);
|
|
955
774
|
}
|
|
956
|
-
|
|
957
775
|
break;
|
|
958
776
|
}
|
|
959
|
-
|
|
960
777
|
case 'TSPropertySignature':
|
|
961
778
|
{
|
|
962
779
|
var _member$computed, _member$static2;
|
|
963
|
-
|
|
964
780
|
const newNode = {
|
|
965
781
|
type: 'PropertyDefinition',
|
|
966
782
|
loc: DUMMY_LOC,
|
|
@@ -978,35 +794,15 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
978
794
|
classMembers.push(newNode);
|
|
979
795
|
break;
|
|
980
796
|
}
|
|
981
|
-
|
|
982
797
|
case 'TSCallSignatureDeclaration':
|
|
983
798
|
{
|
|
984
799
|
var _node$body$callProper;
|
|
985
|
-
|
|
986
|
-
/*
|
|
987
|
-
TODO - callProperties
|
|
988
|
-
It's not valid to directly declare a call property on a class in TS
|
|
989
|
-
You can do it, but it's a big complication in the AST:
|
|
990
|
-
```ts
|
|
991
|
-
declare Class {
|
|
992
|
-
// ...
|
|
993
|
-
}
|
|
994
|
-
interface ClassConstructor {
|
|
995
|
-
new (): Class;
|
|
996
|
-
// call sigs
|
|
997
|
-
(): Type;
|
|
998
|
-
}
|
|
999
|
-
```
|
|
1000
|
-
Let's put a pin in it for now and deal with it later if the need arises.
|
|
1001
|
-
*/
|
|
1002
800
|
return unsupportedDeclaration((_node$body$callProper = node.body.callProperties[0]) != null ? _node$body$callProper : node.body, 'call signatures on classes', node.id, true, node.typeParameters);
|
|
1003
801
|
}
|
|
1004
|
-
|
|
1005
802
|
default:
|
|
1006
803
|
throw unexpectedTranslationError(node.body, `Unexpected member type ${member.type}`);
|
|
1007
804
|
}
|
|
1008
805
|
}
|
|
1009
|
-
|
|
1010
806
|
const superClass = node.extends.length > 0 ? node.extends[0] : undefined;
|
|
1011
807
|
return {
|
|
1012
808
|
type: 'ClassDeclaration',
|
|
@@ -1020,18 +816,14 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
1020
816
|
id: transform.Identifier(node.id, false),
|
|
1021
817
|
implements: node.implements == null ? undefined : node.implements.map(transform.ClassImplements),
|
|
1022
818
|
superClass: superClass == null ? null : superClass.id.type === 'QualifiedTypeIdentifier' ? transform.QualifiedTypeIdentifier(superClass.id) : transform.Identifier(superClass.id, false),
|
|
1023
|
-
|
|
1024
|
-
typeParameters: node.typeParameters == null ? undefined : transform.TypeParameterDeclaration(node.typeParameters)
|
|
1025
|
-
|
|
819
|
+
superTypeArguments: transform.TypeParameterInstantiation(superClass == null ? void 0 : superClass.typeParameters),
|
|
820
|
+
typeParameters: node.typeParameters == null ? undefined : transform.TypeParameterDeclaration(node.typeParameters)
|
|
1026
821
|
};
|
|
1027
822
|
},
|
|
1028
|
-
|
|
1029
823
|
DeclareExportDeclaration(node) {
|
|
1030
824
|
if (node.default === true) {
|
|
1031
825
|
const declaration = node.declaration;
|
|
1032
|
-
|
|
1033
826
|
switch (declaration.type) {
|
|
1034
|
-
// TS doesn't support direct default export for declare'd classes
|
|
1035
827
|
case 'DeclareClass':
|
|
1036
828
|
{
|
|
1037
829
|
const classDecl = transform.DeclareClass(declaration);
|
|
@@ -1047,8 +839,6 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
1047
839
|
exportKind: 'value'
|
|
1048
840
|
}];
|
|
1049
841
|
}
|
|
1050
|
-
// TS doesn't support direct default export for declare'd functions
|
|
1051
|
-
|
|
1052
842
|
case 'DeclareFunction':
|
|
1053
843
|
{
|
|
1054
844
|
const functionDecl = transform.DeclareFunction(declaration);
|
|
@@ -1064,8 +854,6 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
1064
854
|
exportKind: 'value'
|
|
1065
855
|
}];
|
|
1066
856
|
}
|
|
1067
|
-
// TS doesn't support direct default export for declare'd functions
|
|
1068
|
-
|
|
1069
857
|
case 'DeclareComponent':
|
|
1070
858
|
{
|
|
1071
859
|
const functionDecl = transform.DeclareComponent(declaration);
|
|
@@ -1081,8 +869,6 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
1081
869
|
exportKind: 'value'
|
|
1082
870
|
}];
|
|
1083
871
|
}
|
|
1084
|
-
// TS doesn't support direct default export for declare'd functions
|
|
1085
|
-
|
|
1086
872
|
case 'DeclareHook':
|
|
1087
873
|
{
|
|
1088
874
|
const functionDecl = transform.DeclareHook(declaration);
|
|
@@ -1098,44 +884,26 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
1098
884
|
exportKind: 'value'
|
|
1099
885
|
}];
|
|
1100
886
|
}
|
|
1101
|
-
// Flow's declare export default Identifier is ambiguous.
|
|
1102
|
-
// the Identifier might reference a type, or it might reference a value
|
|
1103
|
-
// - If it's a value, then that's all good, TS supports that.
|
|
1104
|
-
// - If it's a type, that's a problem - TS only allows value variables to be exported
|
|
1105
|
-
// so we need to create an intermediate variable to hold the type.
|
|
1106
|
-
|
|
1107
887
|
case 'GenericTypeAnnotation':
|
|
1108
888
|
{
|
|
1109
|
-
const referencedId = declaration.id;
|
|
1110
|
-
// only Identifiers can be handled here.
|
|
1111
|
-
|
|
889
|
+
const referencedId = declaration.id;
|
|
1112
890
|
if (referencedId.type === 'Identifier') {
|
|
1113
891
|
const exportedVar = topScope.set.get(referencedId.name);
|
|
1114
|
-
|
|
1115
892
|
if (exportedVar != null && exportedVar.defs.length === 1) {
|
|
1116
893
|
const def = exportedVar.defs[0];
|
|
1117
|
-
|
|
1118
894
|
switch (def.type) {
|
|
1119
895
|
case 'ImportBinding':
|
|
1120
896
|
{
|
|
1121
|
-
// `import type { Wut } from 'mod'; declare export default Wut;`
|
|
1122
|
-
// `import { type Wut } from 'mod'; declare export default Wut;`
|
|
1123
|
-
// these cases should be wrapped in a variable because they're exporting a type, not a value
|
|
1124
897
|
const specifier = def.node;
|
|
1125
|
-
|
|
1126
898
|
if (specifier.importKind === 'type' || specifier.parent.importKind === 'type') {
|
|
1127
|
-
// fallthrough to the "default" handling
|
|
1128
899
|
break;
|
|
1129
|
-
}
|
|
1130
|
-
|
|
900
|
+
}
|
|
1131
901
|
}
|
|
1132
|
-
|
|
1133
902
|
case 'ClassName':
|
|
1134
903
|
case 'Enum':
|
|
1135
904
|
case 'FunctionName':
|
|
1136
905
|
case 'ImplicitGlobalVariable':
|
|
1137
906
|
case 'Variable':
|
|
1138
|
-
// there's already a variable defined to hold the type
|
|
1139
907
|
return {
|
|
1140
908
|
type: 'ExportDefaultDeclaration',
|
|
1141
909
|
loc: DUMMY_LOC,
|
|
@@ -1146,30 +914,23 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
1146
914
|
},
|
|
1147
915
|
exportKind: 'value'
|
|
1148
916
|
};
|
|
1149
|
-
|
|
1150
917
|
case 'CatchClause':
|
|
1151
918
|
case 'Parameter':
|
|
1152
919
|
case 'TypeParameter':
|
|
1153
920
|
throw translationError(def.node, `Unexpected variable def type: ${def.type}`);
|
|
1154
|
-
|
|
1155
921
|
case 'Type':
|
|
1156
|
-
// fallthrough to the "default" handling
|
|
1157
922
|
break;
|
|
1158
923
|
}
|
|
1159
924
|
}
|
|
1160
|
-
}
|
|
1161
|
-
|
|
925
|
+
}
|
|
1162
926
|
}
|
|
1163
|
-
|
|
1164
927
|
case 'TypeofTypeAnnotation':
|
|
1165
928
|
{
|
|
1166
929
|
if (declaration.type === 'TypeofTypeAnnotation' && declaration.argument.type === 'Identifier') {
|
|
1167
930
|
const name = declaration.argument.name;
|
|
1168
931
|
const exportedVar = topScope.set.get(name);
|
|
1169
|
-
|
|
1170
932
|
if (exportedVar != null && exportedVar.defs.length === 1) {
|
|
1171
933
|
const def = exportedVar.defs[0];
|
|
1172
|
-
|
|
1173
934
|
switch (def.type) {
|
|
1174
935
|
case 'ClassName':
|
|
1175
936
|
{
|
|
@@ -1188,24 +949,10 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
1188
949
|
}
|
|
1189
950
|
}
|
|
1190
951
|
}
|
|
1191
|
-
}
|
|
1192
|
-
|
|
952
|
+
}
|
|
1193
953
|
}
|
|
1194
|
-
|
|
1195
954
|
default:
|
|
1196
955
|
{
|
|
1197
|
-
/*
|
|
1198
|
-
flow allows syntax like
|
|
1199
|
-
```
|
|
1200
|
-
declare export default TypeName;
|
|
1201
|
-
```
|
|
1202
|
-
but TS does not, so we have to declare a temporary variable to
|
|
1203
|
-
reference in the export declaration:
|
|
1204
|
-
```
|
|
1205
|
-
declare const $$EXPORT_DEFAULT_DECLARATION$$: TypeName;
|
|
1206
|
-
export default $$EXPORT_DEFAULT_DECLARATION$$;
|
|
1207
|
-
```
|
|
1208
|
-
*/
|
|
1209
956
|
const SPECIFIER = '$$EXPORT_DEFAULT_DECLARATION$$';
|
|
1210
957
|
return [{
|
|
1211
958
|
type: 'VariableDeclaration',
|
|
@@ -1262,23 +1009,18 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
1262
1009
|
}
|
|
1263
1010
|
}
|
|
1264
1011
|
} else {
|
|
1265
|
-
// eslint-disable-next-line eqeqeq
|
|
1266
1012
|
if (node.source === null) {
|
|
1267
|
-
// eslint-disable-next-line eqeqeq
|
|
1268
1013
|
if (node.declaration === null) {
|
|
1269
1014
|
return {
|
|
1270
1015
|
type: 'ExportNamedDeclaration',
|
|
1271
1016
|
loc: DUMMY_LOC,
|
|
1272
|
-
// flow does not currently support attributes
|
|
1273
1017
|
assertions: [],
|
|
1274
1018
|
declaration: null,
|
|
1275
|
-
// flow does not support declared type exports with specifiers
|
|
1276
1019
|
exportKind: 'value',
|
|
1277
1020
|
source: null,
|
|
1278
1021
|
specifiers: node.specifiers.map(transform.ExportSpecifier)
|
|
1279
1022
|
};
|
|
1280
1023
|
}
|
|
1281
|
-
|
|
1282
1024
|
const declarations = (() => {
|
|
1283
1025
|
switch (node.declaration.type) {
|
|
1284
1026
|
case 'DeclareClass':
|
|
@@ -1286,43 +1028,36 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
1286
1028
|
declaration: transform.DeclareClass(node.declaration),
|
|
1287
1029
|
exportKind: 'value'
|
|
1288
1030
|
}];
|
|
1289
|
-
|
|
1290
1031
|
case 'DeclareComponent':
|
|
1291
1032
|
return [{
|
|
1292
1033
|
declaration: transform.DeclareComponent(node.declaration),
|
|
1293
1034
|
exportKind: 'value'
|
|
1294
1035
|
}];
|
|
1295
|
-
|
|
1296
1036
|
case 'DeclareHook':
|
|
1297
1037
|
return [{
|
|
1298
1038
|
declaration: transform.DeclareHook(node.declaration),
|
|
1299
1039
|
exportKind: 'value'
|
|
1300
1040
|
}];
|
|
1301
|
-
|
|
1302
1041
|
case 'DeclareFunction':
|
|
1303
1042
|
return [{
|
|
1304
1043
|
declaration: transform.DeclareFunction(node.declaration),
|
|
1305
1044
|
exportKind: 'value'
|
|
1306
1045
|
}];
|
|
1307
|
-
|
|
1308
1046
|
case 'DeclareInterface':
|
|
1309
1047
|
return [{
|
|
1310
1048
|
declaration: transform.DeclareInterface(node.declaration),
|
|
1311
1049
|
exportKind: 'type'
|
|
1312
1050
|
}];
|
|
1313
|
-
|
|
1314
1051
|
case 'DeclareOpaqueType':
|
|
1315
1052
|
return [{
|
|
1316
1053
|
declaration: transform.DeclareOpaqueType(node.declaration),
|
|
1317
1054
|
exportKind: 'type'
|
|
1318
1055
|
}];
|
|
1319
|
-
|
|
1320
1056
|
case 'DeclareVariable':
|
|
1321
1057
|
return [{
|
|
1322
1058
|
declaration: transform.DeclareVariable(node.declaration),
|
|
1323
1059
|
exportKind: 'value'
|
|
1324
1060
|
}];
|
|
1325
|
-
|
|
1326
1061
|
case 'DeclareEnum':
|
|
1327
1062
|
{
|
|
1328
1063
|
const result = transform.DeclareEnum(node.declaration);
|
|
@@ -1339,20 +1074,17 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
1339
1074
|
}
|
|
1340
1075
|
}
|
|
1341
1076
|
})();
|
|
1342
|
-
|
|
1343
1077
|
const mappedDeclarations = declarations.map(({
|
|
1344
1078
|
declaration,
|
|
1345
1079
|
exportKind
|
|
1346
1080
|
}) => {
|
|
1347
1081
|
if (declaration.type === 'VariableDeclaration' && declaration.declarations.length === 1) {
|
|
1348
1082
|
const ident = declaration.declarations[0].id;
|
|
1349
|
-
|
|
1350
1083
|
if (ident.type === 'Identifier') {
|
|
1351
1084
|
const name = ident.name;
|
|
1352
1085
|
return [{
|
|
1353
1086
|
type: 'ExportNamedDeclaration',
|
|
1354
1087
|
loc: DUMMY_LOC,
|
|
1355
|
-
// flow does not currently support attributes
|
|
1356
1088
|
assertions: [],
|
|
1357
1089
|
declaration,
|
|
1358
1090
|
exportKind,
|
|
@@ -1387,16 +1119,13 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
1387
1119
|
loc: DUMMY_LOC,
|
|
1388
1120
|
specifiers: [],
|
|
1389
1121
|
exportKind: 'type',
|
|
1390
|
-
// flow does not currently support attributes
|
|
1391
1122
|
assertions: []
|
|
1392
1123
|
}];
|
|
1393
1124
|
}
|
|
1394
1125
|
}
|
|
1395
|
-
|
|
1396
1126
|
const exportNamedDeclaration = {
|
|
1397
1127
|
type: 'ExportNamedDeclaration',
|
|
1398
1128
|
loc: DUMMY_LOC,
|
|
1399
|
-
// flow does not currently support attributes
|
|
1400
1129
|
assertions: [],
|
|
1401
1130
|
declaration,
|
|
1402
1131
|
exportKind,
|
|
@@ -1410,10 +1139,8 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
1410
1139
|
return {
|
|
1411
1140
|
type: 'ExportNamedDeclaration',
|
|
1412
1141
|
loc: DUMMY_LOC,
|
|
1413
|
-
// flow does not currently support attributes
|
|
1414
1142
|
assertions: [],
|
|
1415
1143
|
declaration: null,
|
|
1416
|
-
// flow does not support declared type exports with a source
|
|
1417
1144
|
exportKind: 'value',
|
|
1418
1145
|
source: transform.StringLiteral(node.source),
|
|
1419
1146
|
specifiers: node.specifiers.map(transform.ExportSpecifier)
|
|
@@ -1421,17 +1148,15 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
1421
1148
|
}
|
|
1422
1149
|
}
|
|
1423
1150
|
},
|
|
1424
|
-
|
|
1425
1151
|
DeclareComponent(node) {
|
|
1426
1152
|
const id = transform.Identifier(node.id, false);
|
|
1427
1153
|
const typeParameters = node.typeParameters == null ? undefined : transform.TypeParameterDeclaration(node.typeParameters);
|
|
1428
|
-
const
|
|
1429
|
-
|
|
1154
|
+
const [declaredParams, declaredRest] = normalizeDeclareComponentParams(node.params, node.rest, unexpectedTranslationError);
|
|
1155
|
+
const params = transform.ComponentTypeParameters(declaredParams, declaredRest);
|
|
1430
1156
|
const hasReactImport = isReactImport(node, 'React');
|
|
1431
1157
|
const returnType = {
|
|
1432
1158
|
type: 'TSTypeAnnotation',
|
|
1433
1159
|
loc: DUMMY_LOC,
|
|
1434
|
-
// If no rendersType we assume its ReactNode type.
|
|
1435
1160
|
typeAnnotation: {
|
|
1436
1161
|
type: 'TSTypeReference',
|
|
1437
1162
|
loc: DUMMY_LOC,
|
|
@@ -1445,7 +1170,7 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
1445
1170
|
name: `ReactNode`
|
|
1446
1171
|
}
|
|
1447
1172
|
},
|
|
1448
|
-
|
|
1173
|
+
typeArguments: undefined
|
|
1449
1174
|
}
|
|
1450
1175
|
};
|
|
1451
1176
|
return {
|
|
@@ -1466,7 +1191,6 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
1466
1191
|
typeParameters: typeParameters
|
|
1467
1192
|
};
|
|
1468
1193
|
},
|
|
1469
|
-
|
|
1470
1194
|
ComponentTypeParameters(params, rest) {
|
|
1471
1195
|
if (params.length === 0 && rest != null) {
|
|
1472
1196
|
return [{
|
|
@@ -1481,9 +1205,7 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
1481
1205
|
optional: false
|
|
1482
1206
|
}];
|
|
1483
1207
|
}
|
|
1484
|
-
|
|
1485
1208
|
const flowPropsType = [];
|
|
1486
|
-
|
|
1487
1209
|
if (rest != null) {
|
|
1488
1210
|
flowPropsType.push(constructFlowNode({
|
|
1489
1211
|
type: 'ObjectTypeSpreadProperty',
|
|
@@ -1492,10 +1214,8 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
1492
1214
|
loc: rest.loc
|
|
1493
1215
|
}));
|
|
1494
1216
|
}
|
|
1495
|
-
|
|
1496
1217
|
for (let i = 0; i < params.length; i++) {
|
|
1497
1218
|
var _param$name;
|
|
1498
|
-
|
|
1499
1219
|
const param = params[i];
|
|
1500
1220
|
flowPropsType.push(constructFlowNode({
|
|
1501
1221
|
type: 'ObjectTypeProperty',
|
|
@@ -1516,7 +1236,6 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
1516
1236
|
loc: param.loc
|
|
1517
1237
|
}));
|
|
1518
1238
|
}
|
|
1519
|
-
|
|
1520
1239
|
const tsPropsObjectType = transform.ObjectTypeAnnotation(constructFlowNode({
|
|
1521
1240
|
type: 'ObjectTypeAnnotation',
|
|
1522
1241
|
inexact: false,
|
|
@@ -1538,9 +1257,7 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
1538
1257
|
optional: false
|
|
1539
1258
|
}];
|
|
1540
1259
|
},
|
|
1541
|
-
|
|
1542
1260
|
DeclareHook(node) {
|
|
1543
|
-
// the hook params/returnType are stored as an annotation on the ID...
|
|
1544
1261
|
const id = transform.Identifier(node.id, false);
|
|
1545
1262
|
const functionInfo = transform.FunctionTypeAnnotation(node.id.typeAnnotation.typeAnnotation);
|
|
1546
1263
|
return {
|
|
@@ -1561,9 +1278,7 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
1561
1278
|
typeParameters: functionInfo.typeParameters
|
|
1562
1279
|
};
|
|
1563
1280
|
},
|
|
1564
|
-
|
|
1565
1281
|
DeclareFunction(node) {
|
|
1566
|
-
// the function information is stored as an annotation on the ID...
|
|
1567
1282
|
const id = transform.Identifier(node.id, false);
|
|
1568
1283
|
const functionInfo = transform.FunctionTypeAnnotation(node.id.typeAnnotation.typeAnnotation);
|
|
1569
1284
|
return {
|
|
@@ -1584,14 +1299,11 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
1584
1299
|
typeParameters: functionInfo.typeParameters
|
|
1585
1300
|
};
|
|
1586
1301
|
},
|
|
1587
|
-
|
|
1588
1302
|
DeclareInterface(node) {
|
|
1589
1303
|
const transformedBody = transform.ObjectTypeAnnotation(node.body);
|
|
1590
|
-
|
|
1591
1304
|
if (transformedBody.type !== 'TSTypeLiteral') {
|
|
1592
1305
|
throw translationError(node.body, 'Spreads in interfaces are not allowed');
|
|
1593
1306
|
}
|
|
1594
|
-
|
|
1595
1307
|
return {
|
|
1596
1308
|
type: 'TSInterfaceDeclaration',
|
|
1597
1309
|
loc: DUMMY_LOC,
|
|
@@ -1606,7 +1318,6 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
1606
1318
|
typeParameters: node.typeParameters == null ? undefined : transform.TypeParameterDeclaration(node.typeParameters)
|
|
1607
1319
|
};
|
|
1608
1320
|
},
|
|
1609
|
-
|
|
1610
1321
|
DeclareTypeAlias(node) {
|
|
1611
1322
|
return {
|
|
1612
1323
|
type: 'TSTypeAliasDeclaration',
|
|
@@ -1617,11 +1328,7 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
1617
1328
|
typeParameters: node.typeParameters == null ? undefined : transform.TypeParameterDeclaration(node.typeParameters)
|
|
1618
1329
|
};
|
|
1619
1330
|
},
|
|
1620
|
-
|
|
1621
1331
|
DeclareOpaqueType(node) {
|
|
1622
|
-
// TS doesn't currently have nominal types - https://github.com/Microsoft/Typescript/issues/202
|
|
1623
|
-
// TODO - we could simulate this in a variety of ways
|
|
1624
|
-
// Examples - https://basarat.gitbook.io/typescript/main-1/nominaltyping
|
|
1625
1332
|
if (node.supertype == null && node.typeParameters == null) {
|
|
1626
1333
|
const name = `__${node.id.name}__`;
|
|
1627
1334
|
return {
|
|
@@ -1660,7 +1367,6 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
1660
1367
|
}
|
|
1661
1368
|
};
|
|
1662
1369
|
}
|
|
1663
|
-
|
|
1664
1370
|
return {
|
|
1665
1371
|
type: 'TSTypeAliasDeclaration',
|
|
1666
1372
|
loc: DUMMY_LOC,
|
|
@@ -1673,68 +1379,56 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
1673
1379
|
typeParameters: node.typeParameters == null ? undefined : transform.TypeParameterDeclaration(node.typeParameters)
|
|
1674
1380
|
};
|
|
1675
1381
|
},
|
|
1676
|
-
|
|
1677
1382
|
DeclareVariable(node) {
|
|
1678
1383
|
return {
|
|
1679
1384
|
type: 'VariableDeclaration',
|
|
1680
1385
|
loc: DUMMY_LOC,
|
|
1681
1386
|
declare: true,
|
|
1682
|
-
declarations:
|
|
1683
|
-
type
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
|
|
1687
|
-
|
|
1688
|
-
|
|
1387
|
+
declarations: node.declarations.map(declaration => {
|
|
1388
|
+
if (declaration.id.type !== 'Identifier') {
|
|
1389
|
+
throw translationError(declaration.id, `DeclareVariable: unsupported declarator of type "${declaration.id.type}"`);
|
|
1390
|
+
}
|
|
1391
|
+
return {
|
|
1392
|
+
type: 'VariableDeclarator',
|
|
1393
|
+
loc: DUMMY_LOC,
|
|
1394
|
+
declare: true,
|
|
1395
|
+
id: transform.Identifier(declaration.id, true),
|
|
1396
|
+
init: null
|
|
1397
|
+
};
|
|
1398
|
+
}),
|
|
1689
1399
|
kind: node.kind
|
|
1690
1400
|
};
|
|
1691
1401
|
},
|
|
1692
|
-
|
|
1693
1402
|
DeclareEnum(node) {
|
|
1694
1403
|
return EnumImpl(node);
|
|
1695
1404
|
},
|
|
1696
|
-
|
|
1697
1405
|
EmptyTypeAnnotation(node) {
|
|
1698
|
-
// Flow's `empty` type doesn't map well to any types in TS.
|
|
1699
|
-
// The closest is `never`, but `never` has a number of different semantics
|
|
1700
|
-
// In reality no human code should ever directly use the `empty` type in flow
|
|
1701
|
-
// So let's put a pin in it for now
|
|
1702
1406
|
return unsupportedAnnotation(node, 'empty type');
|
|
1703
1407
|
},
|
|
1704
|
-
|
|
1705
1408
|
EnumDeclaration(node) {
|
|
1706
1409
|
return EnumImpl(node);
|
|
1707
1410
|
},
|
|
1708
|
-
|
|
1709
1411
|
DeclareModuleExports(node) {
|
|
1710
1412
|
throw translationError(node, 'CommonJS exports are not supported.');
|
|
1711
1413
|
},
|
|
1712
|
-
|
|
1713
1414
|
ExistsTypeAnnotation(node) {
|
|
1714
|
-
// The existential type does not map to any types in TS
|
|
1715
|
-
// It's also super deprecated - so let's not ever worry
|
|
1716
1415
|
return unsupportedAnnotation(node, 'existential type');
|
|
1717
1416
|
},
|
|
1718
|
-
|
|
1719
1417
|
ExportAllDeclaration(node) {
|
|
1720
1418
|
return {
|
|
1721
1419
|
type: 'ExportAllDeclaration',
|
|
1722
1420
|
loc: DUMMY_LOC,
|
|
1723
|
-
// flow does not currently support import/export attributes
|
|
1724
1421
|
assertions: [],
|
|
1725
1422
|
exportKind: node.exportKind,
|
|
1726
1423
|
source: transform.StringLiteral(node.source),
|
|
1727
1424
|
exported: node.exported == null ? null : transform.Identifier(node.exported)
|
|
1728
1425
|
};
|
|
1729
1426
|
},
|
|
1730
|
-
|
|
1731
1427
|
ExportNamedDeclaration(node) {
|
|
1732
1428
|
if (node.source != null || node.specifiers.length > 0) {
|
|
1733
|
-
// can never have a declaration with a source
|
|
1734
1429
|
return {
|
|
1735
1430
|
type: 'ExportNamedDeclaration',
|
|
1736
1431
|
loc: DUMMY_LOC,
|
|
1737
|
-
// flow does not currently support import/export attributes
|
|
1738
1432
|
assertions: [],
|
|
1739
1433
|
declaration: null,
|
|
1740
1434
|
exportKind: node.exportKind,
|
|
@@ -1742,12 +1436,10 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
1742
1436
|
specifiers: node.specifiers.map(transform.ExportSpecifier)
|
|
1743
1437
|
};
|
|
1744
1438
|
}
|
|
1745
|
-
|
|
1746
1439
|
const [exportedDeclaration, mergedDeclaration] = (() => {
|
|
1747
1440
|
if (node.declaration == null) {
|
|
1748
1441
|
return [null, null];
|
|
1749
1442
|
}
|
|
1750
|
-
|
|
1751
1443
|
switch (node.declaration.type) {
|
|
1752
1444
|
case 'ClassDeclaration':
|
|
1753
1445
|
case 'ComponentDeclaration':
|
|
@@ -1755,27 +1447,20 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
1755
1447
|
case 'HookDeclaration':
|
|
1756
1448
|
case 'FunctionDeclaration':
|
|
1757
1449
|
case 'VariableDeclaration':
|
|
1758
|
-
// These cases shouldn't happen in flow defs because they have their own special
|
|
1759
|
-
// AST node (DeclareClass, DeclareFunction, DeclareVariable)
|
|
1760
1450
|
throw unexpectedTranslationError(node.declaration, `Unexpected named declaration found ${node.declaration.type}`);
|
|
1761
|
-
|
|
1762
1451
|
case 'EnumDeclaration':
|
|
1763
1452
|
{
|
|
1764
1453
|
const result = transform.EnumDeclaration(node.declaration);
|
|
1765
1454
|
return Array.isArray(result) ? result : [result, null];
|
|
1766
1455
|
}
|
|
1767
|
-
|
|
1768
1456
|
case 'InterfaceDeclaration':
|
|
1769
1457
|
return [transform.InterfaceDeclaration(node.declaration), null];
|
|
1770
|
-
|
|
1771
1458
|
case 'OpaqueType':
|
|
1772
1459
|
return [transform.OpaqueType(node.declaration), null];
|
|
1773
|
-
|
|
1774
1460
|
case 'TypeAlias':
|
|
1775
1461
|
return [transform.TypeAlias(node.declaration), null];
|
|
1776
1462
|
}
|
|
1777
1463
|
})();
|
|
1778
|
-
|
|
1779
1464
|
const mainExport = {
|
|
1780
1465
|
type: 'ExportNamedDeclaration',
|
|
1781
1466
|
loc: DUMMY_LOC,
|
|
@@ -1785,9 +1470,7 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
1785
1470
|
source: null,
|
|
1786
1471
|
specifiers: []
|
|
1787
1472
|
};
|
|
1788
|
-
|
|
1789
1473
|
if (mergedDeclaration != null) {
|
|
1790
|
-
// for cases where there is a merged declaration, TS enforces BOTH are exported
|
|
1791
1474
|
return [mainExport, {
|
|
1792
1475
|
type: 'ExportNamedDeclaration',
|
|
1793
1476
|
loc: DUMMY_LOC,
|
|
@@ -1798,24 +1481,19 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
1798
1481
|
specifiers: []
|
|
1799
1482
|
}];
|
|
1800
1483
|
}
|
|
1801
|
-
|
|
1802
1484
|
return mainExport;
|
|
1803
1485
|
},
|
|
1804
|
-
|
|
1805
1486
|
ExportSpecifier(node) {
|
|
1806
1487
|
return {
|
|
1807
1488
|
type: 'ExportSpecifier',
|
|
1808
1489
|
loc: DUMMY_LOC,
|
|
1809
1490
|
exported: transform.Identifier(node.exported, false),
|
|
1810
1491
|
local: transform.Identifier(node.local, false),
|
|
1811
|
-
// flow does not support inline exportKind for named exports
|
|
1812
1492
|
exportKind: 'value'
|
|
1813
1493
|
};
|
|
1814
1494
|
},
|
|
1815
|
-
|
|
1816
1495
|
FunctionTypeAnnotation(node) {
|
|
1817
1496
|
const params = node.params.map(transform.FunctionTypeParam);
|
|
1818
|
-
|
|
1819
1497
|
if (node.type === 'FunctionTypeAnnotation' && node.this != null) {
|
|
1820
1498
|
params.unshift({
|
|
1821
1499
|
type: 'Identifier',
|
|
@@ -1828,7 +1506,6 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
1828
1506
|
}
|
|
1829
1507
|
});
|
|
1830
1508
|
}
|
|
1831
|
-
|
|
1832
1509
|
if (node.rest != null) {
|
|
1833
1510
|
const rest = node.rest;
|
|
1834
1511
|
params.push({
|
|
@@ -1846,7 +1523,6 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
1846
1523
|
}
|
|
1847
1524
|
});
|
|
1848
1525
|
}
|
|
1849
|
-
|
|
1850
1526
|
return {
|
|
1851
1527
|
type: 'TSFunctionType',
|
|
1852
1528
|
loc: DUMMY_LOC,
|
|
@@ -1859,7 +1535,6 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
1859
1535
|
typeParameters: node.typeParameters == null ? undefined : transform.TypeParameterDeclaration(node.typeParameters)
|
|
1860
1536
|
};
|
|
1861
1537
|
},
|
|
1862
|
-
|
|
1863
1538
|
FunctionTypeParam(node, idx = 0) {
|
|
1864
1539
|
return {
|
|
1865
1540
|
type: 'Identifier',
|
|
@@ -1873,12 +1548,10 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
1873
1548
|
optional: node.optional
|
|
1874
1549
|
};
|
|
1875
1550
|
},
|
|
1876
|
-
|
|
1877
1551
|
GenericTypeAnnotation(node) {
|
|
1878
1552
|
const [fullTypeName, baseId] = (() => {
|
|
1879
1553
|
let names = [];
|
|
1880
1554
|
let currentNode = node.id;
|
|
1881
|
-
|
|
1882
1555
|
while (currentNode != null) {
|
|
1883
1556
|
switch (currentNode.type) {
|
|
1884
1557
|
case 'Identifier':
|
|
@@ -1886,7 +1559,6 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
1886
1559
|
names.unshift(currentNode.name);
|
|
1887
1560
|
return [names.join('.'), currentNode];
|
|
1888
1561
|
}
|
|
1889
|
-
|
|
1890
1562
|
case 'QualifiedTypeIdentifier':
|
|
1891
1563
|
{
|
|
1892
1564
|
names.unshift(currentNode.id.name);
|
|
@@ -1895,54 +1567,40 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
1895
1567
|
}
|
|
1896
1568
|
}
|
|
1897
1569
|
}
|
|
1898
|
-
|
|
1899
1570
|
throw translationError(node, `Invalid program state, types should only contain 'Identifier' and 'QualifiedTypeIdentifier' nodes.`);
|
|
1900
1571
|
})();
|
|
1901
|
-
|
|
1902
1572
|
const assertHasExactlyNTypeParameters = count => {
|
|
1903
1573
|
if (node.typeParameters != null) {
|
|
1904
1574
|
if (node.typeParameters.params.length !== count) {
|
|
1905
1575
|
throw translationError(node, `Expected exactly ${count} type parameter${count > 1 ? 's' : ''} with \`${fullTypeName}\``);
|
|
1906
1576
|
}
|
|
1907
|
-
|
|
1908
1577
|
const res = [];
|
|
1909
|
-
|
|
1910
1578
|
for (const param of node.typeParameters.params) {
|
|
1911
1579
|
res.push(transformTypeAnnotationType(param));
|
|
1912
1580
|
}
|
|
1913
|
-
|
|
1914
1581
|
return res;
|
|
1915
1582
|
}
|
|
1916
|
-
|
|
1917
1583
|
if (count !== 0) {
|
|
1918
1584
|
throw translationError(node, `Expected no type parameters with \`${fullTypeName}\``);
|
|
1919
1585
|
}
|
|
1920
|
-
|
|
1921
1586
|
return [];
|
|
1922
1587
|
};
|
|
1923
|
-
|
|
1924
1588
|
function assertHasTypeParametersInRange(min, max) {
|
|
1925
1589
|
const {
|
|
1926
1590
|
typeParameters
|
|
1927
1591
|
} = node;
|
|
1928
|
-
|
|
1929
1592
|
if (typeParameters == null) {
|
|
1930
1593
|
if (min > 0) {
|
|
1931
1594
|
throw translationError(node, `Expected between ${min} and ${max} type parameters with \`${fullTypeName}\`, but got none.`);
|
|
1932
1595
|
}
|
|
1933
|
-
|
|
1934
1596
|
return [];
|
|
1935
1597
|
}
|
|
1936
|
-
|
|
1937
1598
|
const params = typeParameters.params;
|
|
1938
|
-
|
|
1939
1599
|
if (params.length < min || params.length > max) {
|
|
1940
1600
|
throw translationError(node, `Expected between ${min} and ${max} type parameters with \`${fullTypeName}\`, but got ${params.length}.`);
|
|
1941
1601
|
}
|
|
1942
|
-
|
|
1943
1602
|
return typeParameters.params.map(transformTypeAnnotationType);
|
|
1944
1603
|
}
|
|
1945
|
-
|
|
1946
1604
|
switch (fullTypeName) {
|
|
1947
1605
|
case '$Call':
|
|
1948
1606
|
case '$ObjMap':
|
|
@@ -1950,31 +1608,10 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
1950
1608
|
case '$ObjMapi':
|
|
1951
1609
|
case '$TupleMap':
|
|
1952
1610
|
{
|
|
1953
|
-
/*
|
|
1954
|
-
TODO - I don't think it's possible to make these types work in the generic case.
|
|
1955
|
-
TS has no utility types that allow you to generically mimic this functionality.
|
|
1956
|
-
You really need intimiate knowledge of the user's intent in order to correctly
|
|
1957
|
-
transform the code.
|
|
1958
|
-
For example the simple example for $Call from the flow docs:
|
|
1959
|
-
```
|
|
1960
|
-
type ExtractPropType = <T>({prop: T}) => T;
|
|
1961
|
-
type Obj = {prop: number};
|
|
1962
|
-
type PropType = $Call<ExtractPropType, Obj>;
|
|
1963
|
-
// expected -- typeof PropType === number
|
|
1964
|
-
```
|
|
1965
|
-
The equivalent in TS would be:
|
|
1966
|
-
```
|
|
1967
|
-
type ExtractPropType<T extends { prop: any }> = (arg: T) => T['prop'];
|
|
1968
|
-
type Obj = { prop: number };
|
|
1969
|
-
type PropType = ReturnType<ExtractPropType<Obj>>; // number
|
|
1970
|
-
```
|
|
1971
|
-
*/
|
|
1972
1611
|
return unsupportedAnnotation(node, fullTypeName);
|
|
1973
1612
|
}
|
|
1974
|
-
|
|
1975
1613
|
case '$ArrayBufferView':
|
|
1976
1614
|
{
|
|
1977
|
-
// `$ArrayBufferView` => `ArrayBufferView`
|
|
1978
1615
|
return {
|
|
1979
1616
|
type: 'TSTypeReference',
|
|
1980
1617
|
loc: DUMMY_LOC,
|
|
@@ -1985,10 +1622,8 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
1985
1622
|
}
|
|
1986
1623
|
};
|
|
1987
1624
|
}
|
|
1988
|
-
|
|
1989
1625
|
case '$ArrayLike':
|
|
1990
1626
|
{
|
|
1991
|
-
// `$ArrayLike<T>` => `ArrayLike<T>`
|
|
1992
1627
|
return {
|
|
1993
1628
|
type: 'TSTypeReference',
|
|
1994
1629
|
loc: DUMMY_LOC,
|
|
@@ -1997,18 +1632,16 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
1997
1632
|
loc: DUMMY_LOC,
|
|
1998
1633
|
name: 'ArrayLike'
|
|
1999
1634
|
},
|
|
2000
|
-
|
|
1635
|
+
typeArguments: {
|
|
2001
1636
|
type: 'TSTypeParameterInstantiation',
|
|
2002
1637
|
loc: DUMMY_LOC,
|
|
2003
1638
|
params: assertHasExactlyNTypeParameters(1)
|
|
2004
1639
|
}
|
|
2005
1640
|
};
|
|
2006
1641
|
}
|
|
2007
|
-
|
|
2008
1642
|
case '$Diff':
|
|
2009
1643
|
case '$Rest':
|
|
2010
1644
|
{
|
|
2011
|
-
// `$Diff<A, B>` => `Pick<A, Exclude<keyof A, keyof B>>`
|
|
2012
1645
|
const params = assertHasExactlyNTypeParameters(2);
|
|
2013
1646
|
return {
|
|
2014
1647
|
type: 'TSTypeReference',
|
|
@@ -2018,7 +1651,7 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
2018
1651
|
loc: DUMMY_LOC,
|
|
2019
1652
|
name: 'Pick'
|
|
2020
1653
|
},
|
|
2021
|
-
|
|
1654
|
+
typeArguments: {
|
|
2022
1655
|
type: 'TSTypeParameterInstantiation',
|
|
2023
1656
|
loc: DUMMY_LOC,
|
|
2024
1657
|
params: [params[0], {
|
|
@@ -2029,7 +1662,7 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
2029
1662
|
loc: DUMMY_LOC,
|
|
2030
1663
|
name: 'Exclude'
|
|
2031
1664
|
},
|
|
2032
|
-
|
|
1665
|
+
typeArguments: {
|
|
2033
1666
|
type: 'TSTypeParameterInstantiation',
|
|
2034
1667
|
loc: DUMMY_LOC,
|
|
2035
1668
|
params: [{
|
|
@@ -2048,11 +1681,9 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
2048
1681
|
}
|
|
2049
1682
|
};
|
|
2050
1683
|
}
|
|
2051
|
-
|
|
2052
1684
|
case '$ElementType':
|
|
2053
1685
|
case '$PropertyType':
|
|
2054
1686
|
{
|
|
2055
|
-
// `$ElementType<T, K>` => `T[K]`
|
|
2056
1687
|
const params = assertHasExactlyNTypeParameters(2);
|
|
2057
1688
|
return {
|
|
2058
1689
|
type: 'TSIndexedAccessType',
|
|
@@ -2061,24 +1692,16 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
2061
1692
|
indexType: params[1]
|
|
2062
1693
|
};
|
|
2063
1694
|
}
|
|
2064
|
-
|
|
2065
1695
|
case '$Exact':
|
|
2066
1696
|
{
|
|
2067
|
-
// `$Exact<T>` => `T`
|
|
2068
|
-
// TS has no concept of exact vs inexact types
|
|
2069
1697
|
return assertHasExactlyNTypeParameters(1)[0];
|
|
2070
1698
|
}
|
|
2071
|
-
|
|
2072
1699
|
case '$Exports':
|
|
2073
1700
|
{
|
|
2074
|
-
// `$Exports<'module'>` => `typeof import('module')`
|
|
2075
1701
|
const moduleName = assertHasExactlyNTypeParameters(1)[0];
|
|
2076
|
-
|
|
2077
1702
|
if (moduleName.type !== 'TSLiteralType' || moduleName.literal.type !== 'Literal' || typeof moduleName.literal.value !== 'string') {
|
|
2078
1703
|
throw translationError(node, '$Exports must have a string literal argument');
|
|
2079
|
-
}
|
|
2080
|
-
|
|
2081
|
-
|
|
1704
|
+
}
|
|
2082
1705
|
return {
|
|
2083
1706
|
type: 'TSTypeQuery',
|
|
2084
1707
|
loc: DUMMY_LOC,
|
|
@@ -2087,23 +1710,21 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
2087
1710
|
loc: DUMMY_LOC,
|
|
2088
1711
|
argument: moduleName,
|
|
2089
1712
|
qualifier: null,
|
|
2090
|
-
|
|
1713
|
+
options: null,
|
|
1714
|
+
source: moduleName.literal,
|
|
1715
|
+
typeArguments: null
|
|
2091
1716
|
}
|
|
2092
1717
|
};
|
|
2093
1718
|
}
|
|
2094
|
-
|
|
2095
1719
|
case '$FlowFixMe':
|
|
2096
1720
|
{
|
|
2097
|
-
// `$FlowFixMe` => `any`
|
|
2098
1721
|
return {
|
|
2099
1722
|
type: 'TSAnyKeyword',
|
|
2100
1723
|
loc: DUMMY_LOC
|
|
2101
1724
|
};
|
|
2102
1725
|
}
|
|
2103
|
-
|
|
2104
1726
|
case '$KeyMirror':
|
|
2105
1727
|
{
|
|
2106
|
-
// `$KeyMirror<T>` => `{[K in keyof T]: K}`
|
|
2107
1728
|
return {
|
|
2108
1729
|
type: 'TSMappedType',
|
|
2109
1730
|
loc: DUMMY_LOC,
|
|
@@ -2147,10 +1768,8 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
2147
1768
|
}
|
|
2148
1769
|
};
|
|
2149
1770
|
}
|
|
2150
|
-
|
|
2151
1771
|
case '$Keys':
|
|
2152
1772
|
{
|
|
2153
|
-
// `$Keys<T>` => `keyof T`
|
|
2154
1773
|
return {
|
|
2155
1774
|
type: 'TSTypeOperator',
|
|
2156
1775
|
loc: DUMMY_LOC,
|
|
@@ -2158,11 +1777,8 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
2158
1777
|
typeAnnotation: assertHasExactlyNTypeParameters(1)[0]
|
|
2159
1778
|
};
|
|
2160
1779
|
}
|
|
2161
|
-
|
|
2162
1780
|
case '$NonMaybeType':
|
|
2163
1781
|
{
|
|
2164
|
-
// `$NonMaybeType<T>` => `NonNullable<T>`
|
|
2165
|
-
// Not a great name because `NonNullable` also excludes `undefined`
|
|
2166
1782
|
return {
|
|
2167
1783
|
type: 'TSTypeReference',
|
|
2168
1784
|
loc: DUMMY_LOC,
|
|
@@ -2171,17 +1787,15 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
2171
1787
|
loc: DUMMY_LOC,
|
|
2172
1788
|
name: 'NonNullable'
|
|
2173
1789
|
},
|
|
2174
|
-
|
|
1790
|
+
typeArguments: {
|
|
2175
1791
|
type: 'TSTypeParameterInstantiation',
|
|
2176
1792
|
loc: DUMMY_LOC,
|
|
2177
1793
|
params: assertHasExactlyNTypeParameters(1)
|
|
2178
1794
|
}
|
|
2179
1795
|
};
|
|
2180
1796
|
}
|
|
2181
|
-
|
|
2182
1797
|
case '$ReadOnly':
|
|
2183
1798
|
{
|
|
2184
|
-
// `$ReadOnly<T>` => `Readonly<T>`
|
|
2185
1799
|
return {
|
|
2186
1800
|
type: 'TSTypeReference',
|
|
2187
1801
|
loc: DUMMY_LOC,
|
|
@@ -2190,20 +1804,15 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
2190
1804
|
loc: DUMMY_LOC,
|
|
2191
1805
|
name: 'Readonly'
|
|
2192
1806
|
},
|
|
2193
|
-
|
|
1807
|
+
typeArguments: {
|
|
2194
1808
|
type: 'TSTypeParameterInstantiation',
|
|
2195
1809
|
loc: DUMMY_LOC,
|
|
2196
1810
|
params: assertHasExactlyNTypeParameters(1)
|
|
2197
1811
|
}
|
|
2198
1812
|
};
|
|
2199
1813
|
}
|
|
2200
|
-
|
|
2201
1814
|
case '$ReadOnlyArray':
|
|
2202
1815
|
{
|
|
2203
|
-
// `$ReadOnlyArray<T>` => `ReadonlyArray<T>`
|
|
2204
|
-
//
|
|
2205
|
-
// we could also do => `readonly T[]`
|
|
2206
|
-
// TODO - maybe a config option?
|
|
2207
1816
|
return {
|
|
2208
1817
|
type: 'TSTypeReference',
|
|
2209
1818
|
loc: DUMMY_LOC,
|
|
@@ -2212,14 +1821,13 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
2212
1821
|
loc: DUMMY_LOC,
|
|
2213
1822
|
name: 'ReadonlyArray'
|
|
2214
1823
|
},
|
|
2215
|
-
|
|
1824
|
+
typeArguments: {
|
|
2216
1825
|
type: 'TSTypeParameterInstantiation',
|
|
2217
1826
|
loc: DUMMY_LOC,
|
|
2218
1827
|
params: assertHasExactlyNTypeParameters(1)
|
|
2219
1828
|
}
|
|
2220
1829
|
};
|
|
2221
1830
|
}
|
|
2222
|
-
|
|
2223
1831
|
case '$ReadOnlyMap':
|
|
2224
1832
|
{
|
|
2225
1833
|
return {
|
|
@@ -2230,14 +1838,13 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
2230
1838
|
loc: DUMMY_LOC,
|
|
2231
1839
|
name: 'ReadonlyMap'
|
|
2232
1840
|
},
|
|
2233
|
-
|
|
1841
|
+
typeArguments: {
|
|
2234
1842
|
type: 'TSTypeParameterInstantiation',
|
|
2235
1843
|
loc: DUMMY_LOC,
|
|
2236
1844
|
params: assertHasExactlyNTypeParameters(2)
|
|
2237
1845
|
}
|
|
2238
1846
|
};
|
|
2239
1847
|
}
|
|
2240
|
-
|
|
2241
1848
|
case '$ReadOnlySet':
|
|
2242
1849
|
{
|
|
2243
1850
|
return {
|
|
@@ -2248,18 +1855,16 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
2248
1855
|
loc: DUMMY_LOC,
|
|
2249
1856
|
name: 'ReadonlySet'
|
|
2250
1857
|
},
|
|
2251
|
-
|
|
1858
|
+
typeArguments: {
|
|
2252
1859
|
type: 'TSTypeParameterInstantiation',
|
|
2253
1860
|
loc: DUMMY_LOC,
|
|
2254
1861
|
params: assertHasExactlyNTypeParameters(1)
|
|
2255
1862
|
}
|
|
2256
1863
|
};
|
|
2257
1864
|
}
|
|
2258
|
-
|
|
2259
1865
|
case '$Values':
|
|
2260
1866
|
case 'Values':
|
|
2261
1867
|
{
|
|
2262
|
-
// `$Values<T>` / `Values<T>` => `T[keyof T]`
|
|
2263
1868
|
const transformedType = assertHasExactlyNTypeParameters(1)[0];
|
|
2264
1869
|
return {
|
|
2265
1870
|
type: 'TSIndexedAccessType',
|
|
@@ -2273,16 +1878,12 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
2273
1878
|
}
|
|
2274
1879
|
};
|
|
2275
1880
|
}
|
|
2276
|
-
|
|
2277
1881
|
case 'Class':
|
|
2278
1882
|
{
|
|
2279
|
-
// `Class<T>` => `new (...args: any[]) => T`
|
|
2280
1883
|
const param = assertHasExactlyNTypeParameters(1)[0];
|
|
2281
|
-
|
|
2282
1884
|
if (param.type !== 'TSTypeReference') {
|
|
2283
1885
|
throw translationError(node, 'Expected a type reference within Class<T>');
|
|
2284
1886
|
}
|
|
2285
|
-
|
|
2286
1887
|
return {
|
|
2287
1888
|
type: 'TSConstructorType',
|
|
2288
1889
|
loc: DUMMY_LOC,
|
|
@@ -2315,20 +1916,14 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
2315
1916
|
}
|
|
2316
1917
|
};
|
|
2317
1918
|
}
|
|
2318
|
-
|
|
2319
1919
|
case 'StringPrefix':
|
|
2320
1920
|
{
|
|
2321
1921
|
var _params$;
|
|
2322
|
-
|
|
2323
|
-
// `StringPrefix<foo>` => `foo${string}`
|
|
2324
|
-
// `StringPrefix<foo, T>` => `foo${T}`
|
|
2325
1922
|
const params = assertHasTypeParametersInRange(1, 2);
|
|
2326
1923
|
const prefix = params[0];
|
|
2327
|
-
|
|
2328
1924
|
if (prefix.type !== 'TSLiteralType' || typeof prefix.literal.value !== 'string') {
|
|
2329
1925
|
throw translationError(node, 'Expected a string literal for the first type parameter.');
|
|
2330
1926
|
}
|
|
2331
|
-
|
|
2332
1927
|
const prefixStr = prefix.literal.value;
|
|
2333
1928
|
const remainder = (_params$ = params[1]) != null ? _params$ : {
|
|
2334
1929
|
type: 'TSStringKeyword',
|
|
@@ -2357,20 +1952,14 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
2357
1952
|
types: [remainder]
|
|
2358
1953
|
};
|
|
2359
1954
|
}
|
|
2360
|
-
|
|
2361
1955
|
case 'StringSuffix':
|
|
2362
1956
|
{
|
|
2363
1957
|
var _params$2;
|
|
2364
|
-
|
|
2365
|
-
// `StringSuffix<foo>` => `${string}foo`
|
|
2366
|
-
// `StringSuffix<foo, T>` => `${T}foo`
|
|
2367
1958
|
const params = assertHasTypeParametersInRange(1, 2);
|
|
2368
1959
|
const suffix = params[0];
|
|
2369
|
-
|
|
2370
1960
|
if (suffix.type !== 'TSLiteralType' || typeof suffix.literal.value !== 'string') {
|
|
2371
1961
|
throw translationError(node, 'Expected a string literal for the first type parameter.');
|
|
2372
1962
|
}
|
|
2373
|
-
|
|
2374
1963
|
const suffixStr = suffix.literal.value;
|
|
2375
1964
|
const remainder = (_params$2 = params[1]) != null ? _params$2 : {
|
|
2376
1965
|
type: 'TSStringKeyword',
|
|
@@ -2399,20 +1988,11 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
2399
1988
|
types: [remainder]
|
|
2400
1989
|
};
|
|
2401
1990
|
}
|
|
2402
|
-
}
|
|
2403
|
-
|
|
2404
|
-
|
|
1991
|
+
}
|
|
2405
1992
|
const validReactImportOrGlobal = isValidReactImportOrGlobal(baseId);
|
|
2406
1993
|
const hasReactImport = isReactImport(baseId, baseId.name);
|
|
2407
|
-
|
|
2408
1994
|
if (validReactImportOrGlobal || hasReactImport) {
|
|
2409
1995
|
switch (fullTypeName) {
|
|
2410
|
-
// TODO: In flow this is `ChildrenArray<T> = T | $ReadOnlyArray<ChildrenArray<T>>`.
|
|
2411
|
-
// The recursive nature of it is rarely needed, so we're simplifying this for now
|
|
2412
|
-
// but omitting that aspect. Once we're able to provide utility types for our translations,
|
|
2413
|
-
// we should update this.
|
|
2414
|
-
// React.ChildrenArray<T> -> T | ReadonlyArray<T>
|
|
2415
|
-
// React$ChildrenArray<T> -> T | ReadonlyArray<T>
|
|
2416
1996
|
case 'React.ChildrenArray':
|
|
2417
1997
|
case 'React$ChildrenArray':
|
|
2418
1998
|
{
|
|
@@ -2428,7 +2008,7 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
2428
2008
|
loc: DUMMY_LOC,
|
|
2429
2009
|
name: 'ReadonlyArray'
|
|
2430
2010
|
},
|
|
2431
|
-
|
|
2011
|
+
typeArguments: {
|
|
2432
2012
|
type: 'TSTypeParameterInstantiation',
|
|
2433
2013
|
loc: DUMMY_LOC,
|
|
2434
2014
|
params: [param]
|
|
@@ -2436,24 +2016,17 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
2436
2016
|
}]
|
|
2437
2017
|
};
|
|
2438
2018
|
}
|
|
2439
|
-
// React.Component<A,B> -> React.Component<A,B>
|
|
2440
|
-
// React$Component<A,B> -> React.Component<A,B>
|
|
2441
|
-
|
|
2442
2019
|
case 'React.Component':
|
|
2443
2020
|
case 'React$Component':
|
|
2444
2021
|
{
|
|
2445
2022
|
const typeParameters = node.typeParameters;
|
|
2446
|
-
|
|
2447
2023
|
if (typeParameters == null || typeParameters.params.length === 0) {
|
|
2448
2024
|
throw translationError(node, `Expected at least 1 type parameter with \`${fullTypeName}\``);
|
|
2449
2025
|
}
|
|
2450
|
-
|
|
2451
2026
|
const params = typeParameters.params;
|
|
2452
|
-
|
|
2453
2027
|
if (params.length > 2) {
|
|
2454
2028
|
throw translationError(node, `Expected at no more than 2 type parameters with \`${fullTypeName}\``);
|
|
2455
2029
|
}
|
|
2456
|
-
|
|
2457
2030
|
return {
|
|
2458
2031
|
type: 'TSTypeReference',
|
|
2459
2032
|
loc: DUMMY_LOC,
|
|
@@ -2467,16 +2040,13 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
2467
2040
|
name: 'Component'
|
|
2468
2041
|
}
|
|
2469
2042
|
},
|
|
2470
|
-
|
|
2043
|
+
typeArguments: {
|
|
2471
2044
|
type: 'TSTypeParameterInstantiation',
|
|
2472
2045
|
loc: DUMMY_LOC,
|
|
2473
2046
|
params: params.map(param => transformTypeAnnotationType(param))
|
|
2474
2047
|
}
|
|
2475
2048
|
};
|
|
2476
2049
|
}
|
|
2477
|
-
// React.Context<A> -> React.Context<A>
|
|
2478
|
-
// React$Context<A> -> React.Context<A>
|
|
2479
|
-
|
|
2480
2050
|
case 'React$Context':
|
|
2481
2051
|
case 'React.Context':
|
|
2482
2052
|
return {
|
|
@@ -2492,15 +2062,12 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
2492
2062
|
name: `Context`
|
|
2493
2063
|
}
|
|
2494
2064
|
},
|
|
2495
|
-
|
|
2065
|
+
typeArguments: {
|
|
2496
2066
|
type: 'TSTypeParameterInstantiation',
|
|
2497
2067
|
loc: DUMMY_LOC,
|
|
2498
2068
|
params: assertHasExactlyNTypeParameters(1)
|
|
2499
2069
|
}
|
|
2500
2070
|
};
|
|
2501
|
-
// React.Key -> React.Key
|
|
2502
|
-
// React$Key -> React.Key
|
|
2503
|
-
|
|
2504
2071
|
case 'React.Key':
|
|
2505
2072
|
case 'React$Key':
|
|
2506
2073
|
assertHasExactlyNTypeParameters(0);
|
|
@@ -2518,9 +2085,6 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
2518
2085
|
}
|
|
2519
2086
|
}
|
|
2520
2087
|
};
|
|
2521
|
-
// React.ElementType -> React.ElementType
|
|
2522
|
-
// React$ElementType -> React.ElementType
|
|
2523
|
-
|
|
2524
2088
|
case 'React$ElementType':
|
|
2525
2089
|
case 'React.ElementType':
|
|
2526
2090
|
{
|
|
@@ -2538,11 +2102,9 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
2538
2102
|
name: `ElementType`
|
|
2539
2103
|
}
|
|
2540
2104
|
},
|
|
2541
|
-
|
|
2105
|
+
typeArguments: undefined
|
|
2542
2106
|
};
|
|
2543
2107
|
}
|
|
2544
|
-
// React.Node -> React.ReactNode
|
|
2545
|
-
|
|
2546
2108
|
case 'React$Node':
|
|
2547
2109
|
case 'React.Node':
|
|
2548
2110
|
{
|
|
@@ -2560,11 +2122,9 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
2560
2122
|
name: `ReactNode`
|
|
2561
2123
|
}
|
|
2562
2124
|
},
|
|
2563
|
-
|
|
2125
|
+
typeArguments: undefined
|
|
2564
2126
|
};
|
|
2565
2127
|
}
|
|
2566
|
-
// React.Element<typeof Component> -> React.ReactElement<typeof Component>
|
|
2567
|
-
|
|
2568
2128
|
case 'React$Element':
|
|
2569
2129
|
case 'React.Element':
|
|
2570
2130
|
{
|
|
@@ -2581,16 +2141,13 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
2581
2141
|
name: `ReactElement`
|
|
2582
2142
|
}
|
|
2583
2143
|
},
|
|
2584
|
-
|
|
2144
|
+
typeArguments: {
|
|
2585
2145
|
type: 'TSTypeParameterInstantiation',
|
|
2586
2146
|
loc: DUMMY_LOC,
|
|
2587
2147
|
params: assertHasExactlyNTypeParameters(1)
|
|
2588
2148
|
}
|
|
2589
2149
|
};
|
|
2590
2150
|
}
|
|
2591
|
-
// React.ElementRef<typeof Component> -> React.ComponentRef<typeof Component>
|
|
2592
|
-
// React$ElementRef<typeof Component> -> React.ComponentRef<typeof Component>
|
|
2593
|
-
|
|
2594
2151
|
case 'React$ElementRef':
|
|
2595
2152
|
case 'React.ElementRef':
|
|
2596
2153
|
return {
|
|
@@ -2606,15 +2163,12 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
2606
2163
|
name: `ComponentRef`
|
|
2607
2164
|
}
|
|
2608
2165
|
},
|
|
2609
|
-
|
|
2166
|
+
typeArguments: {
|
|
2610
2167
|
type: 'TSTypeParameterInstantiation',
|
|
2611
2168
|
loc: DUMMY_LOC,
|
|
2612
2169
|
params: assertHasExactlyNTypeParameters(1)
|
|
2613
2170
|
}
|
|
2614
2171
|
};
|
|
2615
|
-
// React$Fragment -> React.Fragment
|
|
2616
|
-
// React.Fragment -> React.Fragment
|
|
2617
|
-
|
|
2618
2172
|
case 'React$FragmentType':
|
|
2619
2173
|
case 'React.Fragment':
|
|
2620
2174
|
assertHasExactlyNTypeParameters(0);
|
|
@@ -2632,8 +2186,6 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
2632
2186
|
}
|
|
2633
2187
|
}
|
|
2634
2188
|
};
|
|
2635
|
-
// React.MixedElement -> React.JSX.Element
|
|
2636
|
-
|
|
2637
2189
|
case 'React$MixedElement':
|
|
2638
2190
|
case 'React.MixedElement':
|
|
2639
2191
|
{
|
|
@@ -2664,12 +2216,9 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
2664
2216
|
name: 'Element'
|
|
2665
2217
|
}
|
|
2666
2218
|
},
|
|
2667
|
-
|
|
2219
|
+
typeArguments: undefined
|
|
2668
2220
|
};
|
|
2669
2221
|
}
|
|
2670
|
-
// React.ComponentType<Config> -> React.ComponentType<Config>
|
|
2671
|
-
// React$ComponentType<Config> -> React.ComponentType<Config>
|
|
2672
|
-
|
|
2673
2222
|
case 'React.ComponentType':
|
|
2674
2223
|
case 'React$ComponentType':
|
|
2675
2224
|
{
|
|
@@ -2686,38 +2235,28 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
2686
2235
|
name: 'ComponentType'
|
|
2687
2236
|
}
|
|
2688
2237
|
},
|
|
2689
|
-
|
|
2238
|
+
typeArguments: {
|
|
2690
2239
|
type: 'TSTypeParameterInstantiation',
|
|
2691
2240
|
loc: DUMMY_LOC,
|
|
2692
2241
|
params: assertHasExactlyNTypeParameters(1)
|
|
2693
2242
|
}
|
|
2694
2243
|
};
|
|
2695
2244
|
}
|
|
2696
|
-
// React.AbstractComponent<Config> -> React.ComponentType<Config>
|
|
2697
|
-
// React$AbstractComponent<Config> -> React.ComponentType<Config>
|
|
2698
|
-
// React.AbstractComponent<Config, Instance> -> React.ComponentType<Config & React.RefAttributes<Instance>>
|
|
2699
|
-
// React$AbstractComponent<Config, Instance> -> React.ComponentType<Config & React.RefAttributes<Instance>>
|
|
2700
|
-
|
|
2701
2245
|
case 'React.AbstractComponent':
|
|
2702
2246
|
case 'React$AbstractComponent':
|
|
2703
2247
|
{
|
|
2704
2248
|
const typeParameters = node.typeParameters;
|
|
2705
|
-
|
|
2706
2249
|
if (typeParameters == null || typeParameters.params.length === 0) {
|
|
2707
2250
|
throw translationError(node, `Expected at least 1 type parameter with \`${fullTypeName}\``);
|
|
2708
2251
|
}
|
|
2709
|
-
|
|
2710
2252
|
const params = typeParameters.params;
|
|
2711
|
-
|
|
2712
2253
|
if (params.length > 3) {
|
|
2713
2254
|
throw translationError(node, `Expected at no more than 3 type parameters with \`${fullTypeName}\``);
|
|
2714
2255
|
}
|
|
2715
|
-
|
|
2716
2256
|
const newParams = (() => {
|
|
2717
2257
|
if (params.length === 1) {
|
|
2718
2258
|
return assertHasExactlyNTypeParameters(1);
|
|
2719
2259
|
}
|
|
2720
|
-
|
|
2721
2260
|
const props = transformTypeAnnotationType(params[0]);
|
|
2722
2261
|
const ref = transformTypeAnnotationType(params[1]);
|
|
2723
2262
|
return [{
|
|
@@ -2740,7 +2279,7 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
2740
2279
|
name: 'RefAttributes'
|
|
2741
2280
|
}
|
|
2742
2281
|
},
|
|
2743
|
-
|
|
2282
|
+
typeArguments: {
|
|
2744
2283
|
type: 'TSTypeParameterInstantiation',
|
|
2745
2284
|
loc: DUMMY_LOC,
|
|
2746
2285
|
params: [ref]
|
|
@@ -2748,7 +2287,6 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
2748
2287
|
}]
|
|
2749
2288
|
}];
|
|
2750
2289
|
})();
|
|
2751
|
-
|
|
2752
2290
|
return {
|
|
2753
2291
|
type: 'TSTypeReference',
|
|
2754
2292
|
loc: DUMMY_LOC,
|
|
@@ -2762,16 +2300,13 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
2762
2300
|
name: 'ComponentType'
|
|
2763
2301
|
}
|
|
2764
2302
|
},
|
|
2765
|
-
|
|
2303
|
+
typeArguments: {
|
|
2766
2304
|
type: 'TSTypeParameterInstantiation',
|
|
2767
2305
|
loc: DUMMY_LOC,
|
|
2768
2306
|
params: newParams
|
|
2769
2307
|
}
|
|
2770
2308
|
};
|
|
2771
2309
|
}
|
|
2772
|
-
// React.ElementProps<A> -> React.ComponentProps<A>
|
|
2773
|
-
// React$ElementProps<A> -> React.ComponentProps<A>
|
|
2774
|
-
|
|
2775
2310
|
case 'React.ElementProps':
|
|
2776
2311
|
case 'React$ElementProps':
|
|
2777
2312
|
{
|
|
@@ -2788,16 +2323,13 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
2788
2323
|
name: 'ComponentProps'
|
|
2789
2324
|
}
|
|
2790
2325
|
},
|
|
2791
|
-
|
|
2326
|
+
typeArguments: {
|
|
2792
2327
|
type: 'TSTypeParameterInstantiation',
|
|
2793
2328
|
loc: DUMMY_LOC,
|
|
2794
2329
|
params: assertHasExactlyNTypeParameters(1)
|
|
2795
2330
|
}
|
|
2796
2331
|
};
|
|
2797
2332
|
}
|
|
2798
|
-
// React.ElementConfig<A> -> React.JSX.LibraryManagedAttributes<A, React.ComponentProps<A>>
|
|
2799
|
-
// React$ElementConfig<A> -> React.JSX.LibraryManagedAttributes<A, React.ComponentProps<A>>
|
|
2800
|
-
|
|
2801
2333
|
case 'React.ElementConfig':
|
|
2802
2334
|
case 'React$ElementConfig':
|
|
2803
2335
|
{
|
|
@@ -2828,7 +2360,7 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
2828
2360
|
name: 'LibraryManagedAttributes'
|
|
2829
2361
|
}
|
|
2830
2362
|
},
|
|
2831
|
-
|
|
2363
|
+
typeArguments: {
|
|
2832
2364
|
type: 'TSTypeParameterInstantiation',
|
|
2833
2365
|
loc: DUMMY_LOC,
|
|
2834
2366
|
params: [param, {
|
|
@@ -2844,7 +2376,7 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
2844
2376
|
name: `ComponentProps`
|
|
2845
2377
|
}
|
|
2846
2378
|
},
|
|
2847
|
-
|
|
2379
|
+
typeArguments: {
|
|
2848
2380
|
type: 'TSTypeParameterInstantiation',
|
|
2849
2381
|
loc: DUMMY_LOC,
|
|
2850
2382
|
params: [param]
|
|
@@ -2853,9 +2385,6 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
2853
2385
|
}
|
|
2854
2386
|
};
|
|
2855
2387
|
}
|
|
2856
|
-
// React.RefSetter<C> -> React.Ref<C>
|
|
2857
|
-
// React$RefSetter<C> -> React.Ref<C>
|
|
2858
|
-
|
|
2859
2388
|
case 'React.RefSetter':
|
|
2860
2389
|
case 'React$RefSetter':
|
|
2861
2390
|
return {
|
|
@@ -2871,26 +2400,23 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
2871
2400
|
name: 'Ref'
|
|
2872
2401
|
}
|
|
2873
2402
|
},
|
|
2874
|
-
|
|
2403
|
+
typeArguments: {
|
|
2875
2404
|
type: 'TSTypeParameterInstantiation',
|
|
2876
2405
|
loc: DUMMY_LOC,
|
|
2877
2406
|
params: assertHasExactlyNTypeParameters(1)
|
|
2878
2407
|
}
|
|
2879
2408
|
};
|
|
2880
|
-
|
|
2881
2409
|
default:
|
|
2882
2410
|
return unsupportedAnnotation(node, fullTypeName);
|
|
2883
2411
|
}
|
|
2884
2412
|
}
|
|
2885
|
-
|
|
2886
2413
|
return {
|
|
2887
2414
|
type: 'TSTypeReference',
|
|
2888
2415
|
loc: DUMMY_LOC,
|
|
2889
2416
|
typeName: node.id.type === 'Identifier' ? transform.Identifier(node.id, false) : transform.QualifiedTypeIdentifier(node.id),
|
|
2890
|
-
|
|
2417
|
+
typeArguments: transform.TypeParameterInstantiation(node.typeParameters)
|
|
2891
2418
|
};
|
|
2892
2419
|
},
|
|
2893
|
-
|
|
2894
2420
|
Identifier(node, includeTypeAnnotation = true) {
|
|
2895
2421
|
return {
|
|
2896
2422
|
type: 'Identifier',
|
|
@@ -2901,7 +2427,6 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
2901
2427
|
} : {})
|
|
2902
2428
|
};
|
|
2903
2429
|
},
|
|
2904
|
-
|
|
2905
2430
|
IndexedAccessType(node) {
|
|
2906
2431
|
return {
|
|
2907
2432
|
type: 'TSIndexedAccessType',
|
|
@@ -2910,11 +2435,9 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
2910
2435
|
indexType: transformTypeAnnotationType(node.indexType)
|
|
2911
2436
|
};
|
|
2912
2437
|
},
|
|
2913
|
-
|
|
2914
2438
|
InterfaceDeclaration(node) {
|
|
2915
2439
|
return transform.DeclareInterface(node);
|
|
2916
2440
|
},
|
|
2917
|
-
|
|
2918
2441
|
ImportAttribute(node) {
|
|
2919
2442
|
return {
|
|
2920
2443
|
type: 'ImportAttribute',
|
|
@@ -2923,7 +2446,6 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
2923
2446
|
value: transform.Literal(node.value)
|
|
2924
2447
|
};
|
|
2925
2448
|
},
|
|
2926
|
-
|
|
2927
2449
|
ImportDeclaration(node) {
|
|
2928
2450
|
const importKind = node.importKind;
|
|
2929
2451
|
const specifiers = [];
|
|
@@ -2948,10 +2470,8 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
2948
2470
|
});
|
|
2949
2471
|
return id;
|
|
2950
2472
|
}
|
|
2951
|
-
|
|
2952
2473
|
return transform.Identifier(spec.local, false);
|
|
2953
2474
|
})();
|
|
2954
|
-
|
|
2955
2475
|
switch (spec.type) {
|
|
2956
2476
|
case 'ImportDefaultSpecifier':
|
|
2957
2477
|
specifiers.push({
|
|
@@ -2960,7 +2480,6 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
2960
2480
|
local: id
|
|
2961
2481
|
});
|
|
2962
2482
|
return;
|
|
2963
|
-
|
|
2964
2483
|
case 'ImportNamespaceSpecifier':
|
|
2965
2484
|
specifiers.push({
|
|
2966
2485
|
type: 'ImportNamespaceSpecifier',
|
|
@@ -2968,7 +2487,6 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
2968
2487
|
local: id
|
|
2969
2488
|
});
|
|
2970
2489
|
return;
|
|
2971
|
-
|
|
2972
2490
|
case 'ImportSpecifier':
|
|
2973
2491
|
specifiers.push({
|
|
2974
2492
|
type: 'ImportSpecifier',
|
|
@@ -2990,37 +2508,29 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
2990
2508
|
}] : [];
|
|
2991
2509
|
return [...out, ...unsupportedSpecifiers];
|
|
2992
2510
|
},
|
|
2993
|
-
|
|
2994
2511
|
InterfaceExtends(node) {
|
|
2995
2512
|
return {
|
|
2996
2513
|
type: 'TSInterfaceHeritage',
|
|
2997
2514
|
loc: DUMMY_LOC,
|
|
2998
2515
|
expression: node.id.type === 'QualifiedTypeIdentifier' ? transform.QualifiedTypeIdentifier(node.id) : transform.Identifier(node.id, false),
|
|
2999
|
-
|
|
2516
|
+
typeArguments: transform.TypeParameterInstantiation(node.typeParameters)
|
|
3000
2517
|
};
|
|
3001
2518
|
},
|
|
3002
|
-
|
|
3003
2519
|
InterfaceTypeAnnotation(node) {
|
|
3004
2520
|
if (node.extends) {
|
|
3005
|
-
// type T = interface extends U, V { ... }
|
|
3006
|
-
// to
|
|
3007
|
-
// type T = U & V & { ... }
|
|
3008
2521
|
return {
|
|
3009
2522
|
type: 'TSIntersectionType',
|
|
3010
2523
|
loc: DUMMY_LOC,
|
|
3011
2524
|
types: [...node.extends.map(ex => ({
|
|
3012
2525
|
type: 'TSTypeReference',
|
|
3013
2526
|
loc: DUMMY_LOC,
|
|
3014
|
-
// Bug: ex.id can be qualified
|
|
3015
2527
|
typeName: transform.Identifier(ex.id, false),
|
|
3016
|
-
|
|
2528
|
+
typeArguments: transform.TypeParameterInstantiation(ex.typeParameters)
|
|
3017
2529
|
})), transform.ObjectTypeAnnotation(node.body)]
|
|
3018
2530
|
};
|
|
3019
2531
|
}
|
|
3020
|
-
|
|
3021
2532
|
return transform.ObjectTypeAnnotation(node.body);
|
|
3022
2533
|
},
|
|
3023
|
-
|
|
3024
2534
|
IntersectionTypeAnnotation(node) {
|
|
3025
2535
|
return {
|
|
3026
2536
|
type: 'TSIntersectionType',
|
|
@@ -3028,36 +2538,28 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
3028
2538
|
types: node.types.map(transformTypeAnnotationType)
|
|
3029
2539
|
};
|
|
3030
2540
|
},
|
|
3031
|
-
|
|
3032
2541
|
Literal(node) {
|
|
3033
2542
|
switch (node.literalType) {
|
|
3034
2543
|
case 'bigint':
|
|
3035
2544
|
return transform.BigIntLiteral(node);
|
|
3036
|
-
|
|
3037
2545
|
case 'boolean':
|
|
3038
2546
|
return transform.BooleanLiteral(node);
|
|
3039
|
-
|
|
3040
2547
|
case 'null':
|
|
3041
2548
|
return transform.NullLiteral(node);
|
|
3042
|
-
|
|
3043
2549
|
case 'numeric':
|
|
3044
2550
|
return transform.NumericLiteral(node);
|
|
3045
|
-
|
|
3046
2551
|
case 'regexp':
|
|
3047
2552
|
return transform.RegExpLiteral(node);
|
|
3048
|
-
|
|
3049
2553
|
case 'string':
|
|
3050
2554
|
return transform.StringLiteral(node);
|
|
3051
2555
|
}
|
|
3052
2556
|
},
|
|
3053
|
-
|
|
3054
2557
|
MixedTypeAnnotation(_node) {
|
|
3055
2558
|
return {
|
|
3056
2559
|
type: 'TSUnknownKeyword',
|
|
3057
2560
|
loc: DUMMY_LOC
|
|
3058
2561
|
};
|
|
3059
2562
|
},
|
|
3060
|
-
|
|
3061
2563
|
NullLiteral(_node) {
|
|
3062
2564
|
return {
|
|
3063
2565
|
type: 'Literal',
|
|
@@ -3066,17 +2568,13 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
3066
2568
|
value: null
|
|
3067
2569
|
};
|
|
3068
2570
|
},
|
|
3069
|
-
|
|
3070
2571
|
NullLiteralTypeAnnotation(_node) {
|
|
3071
2572
|
return {
|
|
3072
2573
|
type: 'TSNullKeyword',
|
|
3073
2574
|
loc: DUMMY_LOC
|
|
3074
2575
|
};
|
|
3075
2576
|
},
|
|
3076
|
-
|
|
3077
2577
|
NullableTypeAnnotation(node) {
|
|
3078
|
-
// TS doesn't support the maybe type, so have to explicitly union in `null | undefined`
|
|
3079
|
-
// `?T` becomes `null | undefined | T`
|
|
3080
2578
|
return {
|
|
3081
2579
|
type: 'TSUnionType',
|
|
3082
2580
|
loc: DUMMY_LOC,
|
|
@@ -3089,7 +2587,6 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
3089
2587
|
}, transformTypeAnnotationType(node.typeAnnotation)]
|
|
3090
2588
|
};
|
|
3091
2589
|
},
|
|
3092
|
-
|
|
3093
2590
|
NumberLiteralTypeAnnotation(node) {
|
|
3094
2591
|
return {
|
|
3095
2592
|
type: 'TSLiteralType',
|
|
@@ -3102,14 +2599,12 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
3102
2599
|
}
|
|
3103
2600
|
};
|
|
3104
2601
|
},
|
|
3105
|
-
|
|
3106
2602
|
NumberTypeAnnotation(_node) {
|
|
3107
2603
|
return {
|
|
3108
2604
|
type: 'TSNumberKeyword',
|
|
3109
2605
|
loc: DUMMY_LOC
|
|
3110
2606
|
};
|
|
3111
2607
|
},
|
|
3112
|
-
|
|
3113
2608
|
NumericLiteral(node) {
|
|
3114
2609
|
return {
|
|
3115
2610
|
type: 'Literal',
|
|
@@ -3118,12 +2613,9 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
3118
2613
|
value: node.value
|
|
3119
2614
|
};
|
|
3120
2615
|
},
|
|
3121
|
-
|
|
3122
2616
|
ObjectTypeAnnotation(node) {
|
|
3123
2617
|
if (node.properties.length === 1 && node.properties[0].type === 'ObjectTypeMappedTypeProperty') {
|
|
3124
2618
|
var _prop$variance, _prop$variance2;
|
|
3125
|
-
|
|
3126
|
-
// Mapped Object Object types must not have other object properties.
|
|
3127
2619
|
const prop = node.properties[0];
|
|
3128
2620
|
const tsProp = {
|
|
3129
2621
|
type: 'TSMappedType',
|
|
@@ -3152,56 +2644,36 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
3152
2644
|
nameType: null
|
|
3153
2645
|
};
|
|
3154
2646
|
return tsProp;
|
|
3155
|
-
}
|
|
3156
|
-
// unfortunately flow has unordered properties storing things
|
|
3157
|
-
// so store all elements with their start index and sort the
|
|
3158
|
-
// list afterward
|
|
3159
|
-
|
|
3160
|
-
|
|
2647
|
+
}
|
|
3161
2648
|
const members = [];
|
|
3162
|
-
|
|
3163
2649
|
for (const callProp of node.callProperties) {
|
|
3164
2650
|
members.push({
|
|
3165
2651
|
start: callProp.range[0],
|
|
3166
2652
|
node: transform.ObjectTypeCallProperty(callProp)
|
|
3167
2653
|
});
|
|
3168
2654
|
}
|
|
3169
|
-
|
|
3170
2655
|
for (const indexer of node.indexers) {
|
|
3171
2656
|
members.push({
|
|
3172
2657
|
start: indexer.range[0],
|
|
3173
2658
|
node: transform.ObjectTypeIndexer(indexer)
|
|
3174
2659
|
});
|
|
3175
2660
|
}
|
|
3176
|
-
/*
|
|
3177
|
-
TODO - internalSlots
|
|
3178
|
-
I don't think there's anything analogous in TS.
|
|
3179
|
-
They're really rarely used (if ever) - so let's just ignore them for now
|
|
3180
|
-
*/
|
|
3181
|
-
|
|
3182
|
-
|
|
3183
2661
|
if (node.internalSlots.length > 0) {
|
|
3184
2662
|
return unsupportedAnnotation(node.internalSlots[0], 'internal slots');
|
|
3185
2663
|
}
|
|
3186
|
-
|
|
3187
2664
|
if (!node.properties.find(FlowESTree.isObjectTypeSpreadProperty)) {
|
|
3188
2665
|
for (const property of node.properties) {
|
|
3189
2666
|
if (property.type === 'ObjectTypeSpreadProperty') {
|
|
3190
|
-
// this is imposible due to the above find condition
|
|
3191
|
-
// this check is purely to satisfy flow
|
|
3192
2667
|
throw unexpectedTranslationError(property, 'Impossible state');
|
|
3193
2668
|
}
|
|
3194
|
-
|
|
3195
2669
|
if (property.type === 'ObjectTypeMappedTypeProperty') {
|
|
3196
2670
|
return unsupportedAnnotation(property, 'object type with mapped type property along with other properties');
|
|
3197
2671
|
}
|
|
3198
|
-
|
|
3199
2672
|
members.push({
|
|
3200
2673
|
start: property.range[0],
|
|
3201
2674
|
node: transform.ObjectTypeProperty(property)
|
|
3202
2675
|
});
|
|
3203
2676
|
}
|
|
3204
|
-
|
|
3205
2677
|
const tsBody = members.sort((a, b) => a.start - b.start).map(({
|
|
3206
2678
|
node
|
|
3207
2679
|
}) => node);
|
|
@@ -3211,88 +2683,22 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
3211
2683
|
members: tsBody
|
|
3212
2684
|
};
|
|
3213
2685
|
} else {
|
|
3214
|
-
|
|
3215
|
-
spreads are a complicate thing for us to handle, sadly.
|
|
3216
|
-
in flow type spreads are modelled after object spreads; meaning that for
|
|
3217
|
-
{ ...A, ...B } - all properties in B will explicitly replace any properties
|
|
3218
|
-
in A of the same name.
|
|
3219
|
-
```
|
|
3220
|
-
type T1 = { a: string };
|
|
3221
|
-
type T2 = { a: number };
|
|
3222
|
-
type T3 = { ...T1, ...T2 };
|
|
3223
|
-
type A = T3['a'] // === number
|
|
3224
|
-
```
|
|
3225
|
-
however in TS there are no object type spreads - you can only merge
|
|
3226
|
-
objects either via the intersection operator or via interface extends.
|
|
3227
|
-
For an interface extends - `interface B extends A { ... }` - TS enforces
|
|
3228
|
-
that the properties of B are all covariantly related to the same named
|
|
3229
|
-
properties in A.
|
|
3230
|
-
So we can't use an interface extends.
|
|
3231
|
-
For a type intersection - `type T = A & B;` - TS will (essentially) merge
|
|
3232
|
-
the types by intersecting each same named property in each type to calculate
|
|
3233
|
-
the resulting type. This has the effect of enforcing the same constraint
|
|
3234
|
-
as the interface case, however instead of an error it causes properties to
|
|
3235
|
-
become `never`:
|
|
3236
|
-
```
|
|
3237
|
-
type T1 = { a: string };
|
|
3238
|
-
type T2 = { a: number };
|
|
3239
|
-
type T3 = T1 & T2;
|
|
3240
|
-
type A = T3['a'] // === string & number === never
|
|
3241
|
-
```
|
|
3242
|
-
So in order for us to model flow's spreads we have to explicitly omit the keys
|
|
3243
|
-
from the proceeding type that might clash. We can do this pretty easily using
|
|
3244
|
-
TS's utility types:
|
|
3245
|
-
```
|
|
3246
|
-
type T1 = { a: string };
|
|
3247
|
-
type T2 = { a: number };
|
|
3248
|
-
type T3 = Omit<T1, keyof T2> & T2;
|
|
3249
|
-
type A = T3['a'] // === number
|
|
3250
|
-
```
|
|
3251
|
-
Unfortunately because we need to solve for the general case object type usage,
|
|
3252
|
-
it's going to be a bit ugly and complicated, sadly.
|
|
3253
|
-
If we had access to type information we would be able to skip some ugliness by
|
|
3254
|
-
checking to see if there is any overlap and skipping the omit step if there isn't.
|
|
3255
|
-
But alas - we're working purely syntactically.
|
|
3256
|
-
```
|
|
3257
|
-
type T = { ...T1, b: string };
|
|
3258
|
-
// becomes
|
|
3259
|
-
type T = Omit<T1, keyof { b: string }> & { b: string };
|
|
3260
|
-
```
|
|
3261
|
-
```
|
|
3262
|
-
type T = { ...T1, ...T2, ...T3, b: string };
|
|
3263
|
-
// becomes
|
|
3264
|
-
type T =
|
|
3265
|
-
& Omit<T1, keyof T2 | keyof T3 | keyof { b: string }>
|
|
3266
|
-
& Omit<T2, keyof T3 | keyof { b: string }>
|
|
3267
|
-
& Omit<T3, keyof { b: string }>
|
|
3268
|
-
& { b: string };
|
|
3269
|
-
```
|
|
3270
|
-
Note that because it's going to be super ugly and complicated - for now we're going to disallow:
|
|
3271
|
-
- spreads in the middle
|
|
3272
|
-
- spreads at the end
|
|
3273
|
-
- spreads of things that aren't "Identifiers"
|
|
3274
|
-
*/
|
|
2686
|
+
var _extractPropertyKeyLi;
|
|
3275
2687
|
if (members.length > 0) {
|
|
3276
2688
|
return unsupportedAnnotation(node, 'object types with spreads, indexers and/or call properties at the same time');
|
|
3277
2689
|
}
|
|
3278
|
-
|
|
3279
2690
|
const typesToIntersect = [];
|
|
3280
|
-
|
|
3281
2691
|
for (const property of node.properties) {
|
|
3282
2692
|
if (property.type === 'ObjectTypeSpreadProperty') {
|
|
3283
2693
|
if (members.length > 0) {
|
|
3284
2694
|
return unsupportedAnnotation(property, 'object types with spreads in the middle or at the end');
|
|
3285
2695
|
}
|
|
3286
|
-
|
|
3287
2696
|
const spreadType = transformTypeAnnotationType(property.argument);
|
|
3288
|
-
|
|
3289
2697
|
if (spreadType.type !== 'TSTypeReference' && spreadType.type !== 'TSTypeQuery') {
|
|
3290
2698
|
return unsupportedAnnotation(property, 'object types with complex spreads');
|
|
3291
2699
|
}
|
|
3292
|
-
|
|
3293
2700
|
typesToIntersect.push(spreadType);
|
|
3294
2701
|
} else if (property.type === 'ObjectTypeMappedTypeProperty') {
|
|
3295
|
-
// TODO - Support mapped types
|
|
3296
2702
|
return unsupportedAnnotation(property, 'object type with mapped type property');
|
|
3297
2703
|
} else {
|
|
3298
2704
|
members.push({
|
|
@@ -3301,7 +2707,6 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
3301
2707
|
});
|
|
3302
2708
|
}
|
|
3303
2709
|
}
|
|
3304
|
-
|
|
3305
2710
|
const tsBody = members.sort((a, b) => a.start - b.start).map(({
|
|
3306
2711
|
node
|
|
3307
2712
|
}) => node);
|
|
@@ -3310,11 +2715,22 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
3310
2715
|
loc: DUMMY_LOC,
|
|
3311
2716
|
members: tsBody
|
|
3312
2717
|
};
|
|
2718
|
+
const objectKeyTypes = (_extractPropertyKeyLi = (0, _TSNodeUtils.extractPropertyKeyLiterals)(tsBody)) != null ? _extractPropertyKeyLi : [{
|
|
2719
|
+
type: 'TSTypeOperator',
|
|
2720
|
+
loc: DUMMY_LOC,
|
|
2721
|
+
operator: 'keyof',
|
|
2722
|
+
typeAnnotation: objectType
|
|
2723
|
+
}];
|
|
3313
2724
|
const intersectionMembers = [];
|
|
3314
|
-
|
|
3315
2725
|
for (let i = 0; i < typesToIntersect.length; i += 1) {
|
|
3316
2726
|
const currentType = typesToIntersect[i];
|
|
3317
2727
|
const remainingTypes = typesToIntersect.slice(i + 1);
|
|
2728
|
+
const omitKeyTypes = [...remainingTypes.map(t => ({
|
|
2729
|
+
type: 'TSTypeOperator',
|
|
2730
|
+
loc: DUMMY_LOC,
|
|
2731
|
+
operator: 'keyof',
|
|
2732
|
+
typeAnnotation: t
|
|
2733
|
+
})), ...objectKeyTypes];
|
|
3318
2734
|
intersectionMembers.push({
|
|
3319
2735
|
type: 'TSTypeReference',
|
|
3320
2736
|
loc: DUMMY_LOC,
|
|
@@ -3323,28 +2739,17 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
3323
2739
|
loc: DUMMY_LOC,
|
|
3324
2740
|
name: 'Omit'
|
|
3325
2741
|
},
|
|
3326
|
-
|
|
2742
|
+
typeArguments: {
|
|
3327
2743
|
type: 'TSTypeParameterInstantiation',
|
|
3328
2744
|
loc: DUMMY_LOC,
|
|
3329
|
-
params: [currentType, {
|
|
2745
|
+
params: [currentType, omitKeyTypes.length === 1 ? omitKeyTypes[0] : {
|
|
3330
2746
|
type: 'TSUnionType',
|
|
3331
2747
|
loc: DUMMY_LOC,
|
|
3332
|
-
types:
|
|
3333
|
-
type: 'TSTypeOperator',
|
|
3334
|
-
loc: DUMMY_LOC,
|
|
3335
|
-
operator: 'keyof',
|
|
3336
|
-
typeAnnotation: t
|
|
3337
|
-
})), {
|
|
3338
|
-
type: 'TSTypeOperator',
|
|
3339
|
-
loc: DUMMY_LOC,
|
|
3340
|
-
operator: 'keyof',
|
|
3341
|
-
typeAnnotation: objectType
|
|
3342
|
-
}]
|
|
2748
|
+
types: omitKeyTypes
|
|
3343
2749
|
}]
|
|
3344
2750
|
}
|
|
3345
2751
|
});
|
|
3346
2752
|
}
|
|
3347
|
-
|
|
3348
2753
|
intersectionMembers.push(objectType);
|
|
3349
2754
|
return {
|
|
3350
2755
|
type: 'TSIntersectionType',
|
|
@@ -3353,9 +2758,7 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
3353
2758
|
};
|
|
3354
2759
|
}
|
|
3355
2760
|
},
|
|
3356
|
-
|
|
3357
2761
|
ObjectTypeCallProperty(node) {
|
|
3358
|
-
// the info is stored on the "value"
|
|
3359
2762
|
const func = transform.FunctionTypeAnnotation(node.value);
|
|
3360
2763
|
return {
|
|
3361
2764
|
type: 'TSCallSignatureDeclaration',
|
|
@@ -3365,13 +2768,10 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
3365
2768
|
typeParameters: func.typeParameters
|
|
3366
2769
|
};
|
|
3367
2770
|
},
|
|
3368
|
-
|
|
3369
2771
|
ObjectTypeIndexer(node) {
|
|
3370
2772
|
var _node$variance3, _node$variance4;
|
|
3371
|
-
|
|
3372
2773
|
if (node.key.type === 'GenericTypeAnnotation') {
|
|
3373
2774
|
var _node$variance, _node$variance2;
|
|
3374
|
-
|
|
3375
2775
|
const ident = node.key.id.type === 'Identifier' ? node.key.id : node.key.id.id;
|
|
3376
2776
|
return {
|
|
3377
2777
|
type: 'TSPropertySignature',
|
|
@@ -3401,7 +2801,6 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
3401
2801
|
}
|
|
3402
2802
|
};
|
|
3403
2803
|
}
|
|
3404
|
-
|
|
3405
2804
|
return {
|
|
3406
2805
|
type: 'TSIndexSignature',
|
|
3407
2806
|
loc: DUMMY_LOC,
|
|
@@ -3424,14 +2823,11 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
3424
2823
|
}
|
|
3425
2824
|
};
|
|
3426
2825
|
},
|
|
3427
|
-
|
|
3428
2826
|
ObjectTypeProperty(node) {
|
|
3429
2827
|
var _node$variance5, _node$variance6;
|
|
3430
|
-
|
|
3431
2828
|
const [key, computed] = (() => {
|
|
3432
2829
|
if (node.key.type === 'Identifier' && node.key.name.startsWith('@@')) {
|
|
3433
2830
|
const name = node.key.name.slice(2);
|
|
3434
|
-
|
|
3435
2831
|
if (node.method === true && wellKnownSymbols.has(name)) {
|
|
3436
2832
|
return [{
|
|
3437
2833
|
type: 'MemberExpression',
|
|
@@ -3453,21 +2849,14 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
3453
2849
|
}, true];
|
|
3454
2850
|
}
|
|
3455
2851
|
}
|
|
3456
|
-
|
|
3457
2852
|
const key = node.key.type === 'Identifier' ? transform.Identifier(node.key) : node.key.literalType === 'string' ? transform.StringLiteral(node.key) : null;
|
|
3458
|
-
|
|
3459
2853
|
if (key == null) {
|
|
3460
2854
|
throw unexpectedTranslationError(node, 'Unsupported key type');
|
|
3461
2855
|
}
|
|
3462
|
-
|
|
3463
2856
|
return [key, false];
|
|
3464
2857
|
})();
|
|
3465
|
-
|
|
3466
2858
|
if (node.method === true) {
|
|
3467
|
-
|
|
3468
|
-
// TS has separate nodes for methods and properties
|
|
3469
|
-
const func = transform.FunctionTypeAnnotation(node.value); // $FlowFixMe[incompatible-type] `computed` is set dynamically
|
|
3470
|
-
|
|
2859
|
+
const func = transform.FunctionTypeAnnotation(node.value);
|
|
3471
2860
|
return {
|
|
3472
2861
|
type: 'TSMethodSignature',
|
|
3473
2862
|
loc: DUMMY_LOC,
|
|
@@ -3481,12 +2870,8 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
3481
2870
|
typeParameters: func.typeParameters
|
|
3482
2871
|
};
|
|
3483
2872
|
}
|
|
3484
|
-
|
|
3485
2873
|
if (node.kind === 'get' || node.kind === 'set') {
|
|
3486
|
-
|
|
3487
|
-
// TS treats them as method signatures
|
|
3488
|
-
const func = transform.FunctionTypeAnnotation(node.value); // $FlowFixMe[incompatible-type] `computed` is set dynamically
|
|
3489
|
-
|
|
2874
|
+
const func = transform.FunctionTypeAnnotation(node.value);
|
|
3490
2875
|
return {
|
|
3491
2876
|
type: 'TSMethodSignature',
|
|
3492
2877
|
loc: DUMMY_LOC,
|
|
@@ -3495,15 +2880,11 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
3495
2880
|
kind: node.kind,
|
|
3496
2881
|
optional: false,
|
|
3497
2882
|
params: func.params,
|
|
3498
|
-
// TS setters must not have a return type
|
|
3499
2883
|
returnType: node.kind === 'set' ? undefined : func.returnType,
|
|
3500
2884
|
static: node.static,
|
|
3501
|
-
// TS accessors cannot have type parameters
|
|
3502
2885
|
typeParameters: undefined
|
|
3503
2886
|
};
|
|
3504
|
-
}
|
|
3505
|
-
|
|
3506
|
-
|
|
2887
|
+
}
|
|
3507
2888
|
return {
|
|
3508
2889
|
type: 'TSPropertySignature',
|
|
3509
2890
|
loc: DUMMY_LOC,
|
|
@@ -3515,25 +2896,17 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
3515
2896
|
typeAnnotation: {
|
|
3516
2897
|
type: 'TSTypeAnnotation',
|
|
3517
2898
|
loc: DUMMY_LOC,
|
|
3518
|
-
typeAnnotation: transformTypeAnnotationType(node.value)
|
|
2899
|
+
typeAnnotation: node.optional === true ? (0, _TSNodeUtils.ensureTypeIncludesUndefined)(transformTypeAnnotationType(node.value)) : transformTypeAnnotationType(node.value)
|
|
3519
2900
|
}
|
|
3520
2901
|
};
|
|
3521
2902
|
},
|
|
3522
|
-
|
|
3523
2903
|
OpaqueType(node) {
|
|
3524
2904
|
return transform.DeclareOpaqueType(node);
|
|
3525
2905
|
},
|
|
3526
|
-
|
|
3527
2906
|
OptionalIndexedAccessType(node) {
|
|
3528
|
-
// Foo?.[A][B]
|
|
3529
|
-
// ^^^^^^^^ optional = true
|
|
3530
|
-
// ^^^^^^^^^^^ optional = false
|
|
3531
2907
|
if (node.optional === false) {
|
|
3532
2908
|
return transform.IndexedAccessType(node);
|
|
3533
|
-
}
|
|
3534
|
-
// `T?.[K]` becomes `NonNullable<T>[K]`
|
|
3535
|
-
|
|
3536
|
-
|
|
2909
|
+
}
|
|
3537
2910
|
return {
|
|
3538
2911
|
type: 'TSIndexedAccessType',
|
|
3539
2912
|
loc: DUMMY_LOC,
|
|
@@ -3545,7 +2918,7 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
3545
2918
|
loc: DUMMY_LOC,
|
|
3546
2919
|
name: 'NonNullable'
|
|
3547
2920
|
},
|
|
3548
|
-
|
|
2921
|
+
typeArguments: {
|
|
3549
2922
|
type: 'TSTypeParameterInstantiation',
|
|
3550
2923
|
loc: DUMMY_LOC,
|
|
3551
2924
|
params: [transformTypeAnnotationType(node.objectType)]
|
|
@@ -3554,7 +2927,6 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
3554
2927
|
indexType: transformTypeAnnotationType(node.indexType)
|
|
3555
2928
|
};
|
|
3556
2929
|
},
|
|
3557
|
-
|
|
3558
2930
|
QualifiedTypeIdentifier(node) {
|
|
3559
2931
|
const qual = node.qualification;
|
|
3560
2932
|
return {
|
|
@@ -3564,7 +2936,6 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
3564
2936
|
right: transform.Identifier(node.id, false)
|
|
3565
2937
|
};
|
|
3566
2938
|
},
|
|
3567
|
-
|
|
3568
2939
|
QualifiedTypeofIdentifier(node) {
|
|
3569
2940
|
const qual = node.qualification;
|
|
3570
2941
|
return {
|
|
@@ -3574,7 +2945,6 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
3574
2945
|
right: transform.Identifier(node.id, false)
|
|
3575
2946
|
};
|
|
3576
2947
|
},
|
|
3577
|
-
|
|
3578
2948
|
RegExpLiteral(node) {
|
|
3579
2949
|
return {
|
|
3580
2950
|
type: 'Literal',
|
|
@@ -3587,7 +2957,6 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
3587
2957
|
value: node.value
|
|
3588
2958
|
};
|
|
3589
2959
|
},
|
|
3590
|
-
|
|
3591
2960
|
StringLiteral(node) {
|
|
3592
2961
|
return {
|
|
3593
2962
|
type: 'Literal',
|
|
@@ -3596,7 +2965,6 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
3596
2965
|
value: node.value
|
|
3597
2966
|
};
|
|
3598
2967
|
},
|
|
3599
|
-
|
|
3600
2968
|
StringLiteralTypeAnnotation(node) {
|
|
3601
2969
|
return {
|
|
3602
2970
|
type: 'TSLiteralType',
|
|
@@ -3609,28 +2977,24 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
3609
2977
|
}
|
|
3610
2978
|
};
|
|
3611
2979
|
},
|
|
3612
|
-
|
|
3613
2980
|
StringTypeAnnotation(_node) {
|
|
3614
2981
|
return {
|
|
3615
2982
|
type: 'TSStringKeyword',
|
|
3616
2983
|
loc: DUMMY_LOC
|
|
3617
2984
|
};
|
|
3618
2985
|
},
|
|
3619
|
-
|
|
3620
2986
|
SymbolTypeAnnotation(_node) {
|
|
3621
2987
|
return {
|
|
3622
2988
|
type: 'TSSymbolKeyword',
|
|
3623
2989
|
loc: DUMMY_LOC
|
|
3624
2990
|
};
|
|
3625
2991
|
},
|
|
3626
|
-
|
|
3627
2992
|
ThisTypeAnnotation(_node) {
|
|
3628
2993
|
return {
|
|
3629
2994
|
type: 'TSThisType',
|
|
3630
2995
|
loc: DUMMY_LOC
|
|
3631
2996
|
};
|
|
3632
2997
|
},
|
|
3633
|
-
|
|
3634
2998
|
TupleTypeAnnotation(node) {
|
|
3635
2999
|
const allReadOnly = node.elementTypes.length > 0 && node.elementTypes.every(element => element.type === 'TupleTypeLabeledElement' && element.variance != null && (element.variance.kind === 'plus' || element.variance.kind === 'readonly'));
|
|
3636
3000
|
const elems = node.elementTypes.map(element => {
|
|
@@ -3639,7 +3003,6 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
3639
3003
|
if (!allReadOnly && element.variance != null) {
|
|
3640
3004
|
return unsupportedAnnotation(element, 'tuple type element variance annotations');
|
|
3641
3005
|
}
|
|
3642
|
-
|
|
3643
3006
|
return {
|
|
3644
3007
|
type: 'TSNamedTupleMember',
|
|
3645
3008
|
loc: DUMMY_LOC,
|
|
@@ -3647,7 +3010,6 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
3647
3010
|
optional: element.optional,
|
|
3648
3011
|
elementType: transformTypeAnnotationType(element.elementType)
|
|
3649
3012
|
};
|
|
3650
|
-
|
|
3651
3013
|
case 'TupleTypeSpreadElement':
|
|
3652
3014
|
{
|
|
3653
3015
|
const annot = transformTypeAnnotationType(element.typeAnnotation);
|
|
@@ -3663,7 +3025,6 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
3663
3025
|
} : annot
|
|
3664
3026
|
};
|
|
3665
3027
|
}
|
|
3666
|
-
|
|
3667
3028
|
default:
|
|
3668
3029
|
return transformTypeAnnotationType(element);
|
|
3669
3030
|
}
|
|
@@ -3692,11 +3053,9 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
3692
3053
|
typeAnnotation: tupleAnnot
|
|
3693
3054
|
} : tupleAnnot;
|
|
3694
3055
|
},
|
|
3695
|
-
|
|
3696
3056
|
TypeAlias(node) {
|
|
3697
3057
|
return transform.DeclareTypeAlias(node);
|
|
3698
3058
|
},
|
|
3699
|
-
|
|
3700
3059
|
TypeAnnotation(node) {
|
|
3701
3060
|
return {
|
|
3702
3061
|
type: 'TSTypeAnnotation',
|
|
@@ -3704,7 +3063,6 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
3704
3063
|
typeAnnotation: transformTypeAnnotationType(node.typeAnnotation)
|
|
3705
3064
|
};
|
|
3706
3065
|
},
|
|
3707
|
-
|
|
3708
3066
|
TypeofTypeAnnotation(node) {
|
|
3709
3067
|
switch (node.argument.type) {
|
|
3710
3068
|
case 'Identifier':
|
|
@@ -3712,39 +3070,18 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
3712
3070
|
type: 'TSTypeQuery',
|
|
3713
3071
|
loc: DUMMY_LOC,
|
|
3714
3072
|
exprName: transform.Identifier(node.argument),
|
|
3715
|
-
|
|
3073
|
+
typeArguments: undefined
|
|
3716
3074
|
};
|
|
3717
|
-
|
|
3718
3075
|
case 'QualifiedTypeofIdentifier':
|
|
3719
3076
|
return {
|
|
3720
3077
|
type: 'TSTypeQuery',
|
|
3721
3078
|
loc: DUMMY_LOC,
|
|
3722
3079
|
exprName: transform.QualifiedTypeofIdentifier(node.argument),
|
|
3723
|
-
|
|
3080
|
+
typeArguments: undefined
|
|
3724
3081
|
};
|
|
3725
3082
|
}
|
|
3726
3083
|
},
|
|
3727
|
-
|
|
3728
3084
|
TypeParameter(node) {
|
|
3729
|
-
/*
|
|
3730
|
-
TODO - flow models variance as explicit syntax, but but TS resolves it automatically
|
|
3731
|
-
TS does have syntax for explicit variance, but you can introduce a TS error if the
|
|
3732
|
-
marked parameter isn't used in the location that TS expects them to be in.
|
|
3733
|
-
To make it easier for now let's just rely on TS's auto-resolution.
|
|
3734
|
-
```
|
|
3735
|
-
const variance =
|
|
3736
|
-
new Set(
|
|
3737
|
-
node.variance == null
|
|
3738
|
-
? // by default flow generics act invariantly
|
|
3739
|
-
['in', 'out']
|
|
3740
|
-
: node.variance.kind === 'plus'
|
|
3741
|
-
? // covariant
|
|
3742
|
-
['out']
|
|
3743
|
-
: // contravariant
|
|
3744
|
-
['in'],
|
|
3745
|
-
);
|
|
3746
|
-
```
|
|
3747
|
-
*/
|
|
3748
3085
|
return {
|
|
3749
3086
|
type: 'TSTypeParameter',
|
|
3750
3087
|
loc: DUMMY_LOC,
|
|
@@ -3756,12 +3093,9 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
3756
3093
|
constraint: node.bound == null ? undefined : transformTypeAnnotationType(node.bound.typeAnnotation),
|
|
3757
3094
|
default: node.default == null ? undefined : transformTypeAnnotationType(node.default),
|
|
3758
3095
|
in: false,
|
|
3759
|
-
out: false
|
|
3760
|
-
// out: variance.has('out'),
|
|
3761
|
-
|
|
3096
|
+
out: false
|
|
3762
3097
|
};
|
|
3763
3098
|
},
|
|
3764
|
-
|
|
3765
3099
|
TypeParameterDeclaration(node) {
|
|
3766
3100
|
return {
|
|
3767
3101
|
type: 'TSTypeParameterDeclaration',
|
|
@@ -3769,21 +3103,16 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
3769
3103
|
params: node.params.map(transform.TypeParameter)
|
|
3770
3104
|
};
|
|
3771
3105
|
},
|
|
3772
|
-
|
|
3773
3106
|
TypeParameterInstantiation(node) {
|
|
3774
|
-
// Empty parameters in Flow are valid, but TS requires at least one parameter.
|
|
3775
|
-
// This ensures empty type parameters are not created in TS
|
|
3776
3107
|
if (node == null || node.params.length === 0) {
|
|
3777
3108
|
return undefined;
|
|
3778
3109
|
}
|
|
3779
|
-
|
|
3780
3110
|
return {
|
|
3781
3111
|
type: 'TSTypeParameterInstantiation',
|
|
3782
3112
|
loc: DUMMY_LOC,
|
|
3783
3113
|
params: node.params.map(transformTypeAnnotationType)
|
|
3784
3114
|
};
|
|
3785
3115
|
},
|
|
3786
|
-
|
|
3787
3116
|
UnionTypeAnnotation(node) {
|
|
3788
3117
|
return {
|
|
3789
3118
|
type: 'TSUnionType',
|
|
@@ -3791,35 +3120,30 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
3791
3120
|
types: node.types.map(transformTypeAnnotationType)
|
|
3792
3121
|
};
|
|
3793
3122
|
},
|
|
3794
|
-
|
|
3795
3123
|
VoidTypeAnnotation(_node) {
|
|
3796
3124
|
return {
|
|
3797
3125
|
type: 'TSVoidKeyword',
|
|
3798
3126
|
loc: DUMMY_LOC
|
|
3799
3127
|
};
|
|
3800
3128
|
},
|
|
3801
|
-
|
|
3802
3129
|
NeverTypeAnnotation(_node) {
|
|
3803
3130
|
return {
|
|
3804
3131
|
type: 'TSNeverKeyword',
|
|
3805
3132
|
loc: DUMMY_LOC
|
|
3806
3133
|
};
|
|
3807
3134
|
},
|
|
3808
|
-
|
|
3809
3135
|
UndefinedTypeAnnotation(_node) {
|
|
3810
3136
|
return {
|
|
3811
3137
|
type: 'TSUndefinedKeyword',
|
|
3812
3138
|
loc: DUMMY_LOC
|
|
3813
3139
|
};
|
|
3814
3140
|
},
|
|
3815
|
-
|
|
3816
3141
|
UnknownTypeAnnotation(_node) {
|
|
3817
3142
|
return {
|
|
3818
3143
|
type: 'TSUnknownKeyword',
|
|
3819
3144
|
loc: DUMMY_LOC
|
|
3820
3145
|
};
|
|
3821
3146
|
},
|
|
3822
|
-
|
|
3823
3147
|
ConditionalTypeAnnotation(node) {
|
|
3824
3148
|
return {
|
|
3825
3149
|
type: 'TSConditionalType',
|
|
@@ -3830,7 +3154,6 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
3830
3154
|
falseType: transformTypeAnnotationType(node.falseType)
|
|
3831
3155
|
};
|
|
3832
3156
|
},
|
|
3833
|
-
|
|
3834
3157
|
TypePredicateAnnotation(node) {
|
|
3835
3158
|
return {
|
|
3836
3159
|
type: 'TSTypePredicate',
|
|
@@ -3844,7 +3167,6 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
3844
3167
|
}
|
|
3845
3168
|
};
|
|
3846
3169
|
},
|
|
3847
|
-
|
|
3848
3170
|
InferTypeAnnotation(node) {
|
|
3849
3171
|
return {
|
|
3850
3172
|
type: 'TSInferType',
|
|
@@ -3852,7 +3174,6 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
3852
3174
|
typeParameter: transform.TypeParameter(node.typeParameter)
|
|
3853
3175
|
};
|
|
3854
3176
|
},
|
|
3855
|
-
|
|
3856
3177
|
KeyofTypeAnnotation(node) {
|
|
3857
3178
|
return {
|
|
3858
3179
|
type: 'TSTypeOperator',
|
|
@@ -3861,7 +3182,6 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
3861
3182
|
typeAnnotation: transformTypeAnnotationType(node.argument)
|
|
3862
3183
|
};
|
|
3863
3184
|
},
|
|
3864
|
-
|
|
3865
3185
|
TypeOperator(node) {
|
|
3866
3186
|
switch (node.operator) {
|
|
3867
3187
|
case 'renders':
|
|
@@ -3882,21 +3202,18 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
3882
3202
|
name: `ReactNode`
|
|
3883
3203
|
}
|
|
3884
3204
|
},
|
|
3885
|
-
|
|
3205
|
+
typeArguments: undefined
|
|
3886
3206
|
};
|
|
3887
3207
|
}
|
|
3888
3208
|
}
|
|
3889
3209
|
},
|
|
3890
|
-
|
|
3891
3210
|
ComponentTypeAnnotation(node) {
|
|
3892
3211
|
const typeParameters = node.typeParameters == null ? undefined : transform.TypeParameterDeclaration(node.typeParameters);
|
|
3893
|
-
const params = transform.ComponentTypeParameters(node.params, node.rest);
|
|
3894
|
-
|
|
3212
|
+
const params = transform.ComponentTypeParameters(node.params, node.rest);
|
|
3895
3213
|
const hasReactImport = isReactImport(node, 'React');
|
|
3896
3214
|
const returnType = {
|
|
3897
3215
|
type: 'TSTypeAnnotation',
|
|
3898
3216
|
loc: DUMMY_LOC,
|
|
3899
|
-
// If no rendersType we assume its ReactNode type.
|
|
3900
3217
|
typeAnnotation: {
|
|
3901
3218
|
type: 'TSTypeReference',
|
|
3902
3219
|
loc: DUMMY_LOC,
|
|
@@ -3910,7 +3227,7 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
3910
3227
|
name: `ReactNode`
|
|
3911
3228
|
}
|
|
3912
3229
|
},
|
|
3913
|
-
|
|
3230
|
+
typeArguments: undefined
|
|
3914
3231
|
}
|
|
3915
3232
|
};
|
|
3916
3233
|
return {
|
|
@@ -3921,17 +3238,11 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
3921
3238
|
returnType
|
|
3922
3239
|
};
|
|
3923
3240
|
}
|
|
3924
|
-
|
|
3925
|
-
}; // wrap each transform so that we automatically preserve jsdoc comments
|
|
3926
|
-
// this just saves us manually wiring up every single case
|
|
3927
|
-
|
|
3241
|
+
};
|
|
3928
3242
|
for (const key of Object.keys(transform)) {
|
|
3929
|
-
const originalFn = transform[key];
|
|
3930
|
-
// $FlowExpectedError[missing-local-annot]
|
|
3931
|
-
|
|
3243
|
+
const originalFn = transform[key];
|
|
3932
3244
|
transform[key] = (node, ...args) => {
|
|
3933
3245
|
const result = originalFn(node, ...args);
|
|
3934
|
-
|
|
3935
3246
|
if (node != null && result != null) {
|
|
3936
3247
|
if (Array.isArray(result)) {
|
|
3937
3248
|
cloneJSDocCommentsToNewNode(node, result[0]);
|
|
@@ -3939,10 +3250,8 @@ const getTransforms = (originalCode, scopeManager, opts) => {
|
|
|
3939
3250
|
cloneJSDocCommentsToNewNode(node, result);
|
|
3940
3251
|
}
|
|
3941
3252
|
}
|
|
3942
|
-
|
|
3943
3253
|
return result;
|
|
3944
3254
|
};
|
|
3945
3255
|
}
|
|
3946
|
-
|
|
3947
3256
|
return [transform, code];
|
|
3948
3257
|
};
|