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.
Files changed (37) hide show
  1. package/dist/TSDefToFlowDef.js +66 -327
  2. package/dist/TSDefToFlowDef.js.flow +70 -35
  3. package/dist/flowDefToTSDef.js +134 -825
  4. package/dist/flowDefToTSDef.js.flow +196 -100
  5. package/dist/flowImportTo.js +5 -25
  6. package/dist/flowImportTo.js.flow +4 -4
  7. package/dist/flowToFlowDef.js +190 -379
  8. package/dist/flowToFlowDef.js.flow +109 -27
  9. package/dist/flowToJS.js +3 -19
  10. package/dist/flowToJS.js.flow +5 -5
  11. package/dist/index.js +12 -50
  12. package/dist/index.js.flow +1 -1
  13. package/dist/src/TSDefToFlowDef.js +66 -327
  14. package/dist/src/flowDefToTSDef.js +134 -825
  15. package/dist/src/flowImportTo.js +5 -25
  16. package/dist/src/flowToFlowDef.js +190 -379
  17. package/dist/src/flowToJS.js +3 -19
  18. package/dist/src/index.js +12 -50
  19. package/dist/src/utils/DocblockUtils.js +4 -14
  20. package/dist/src/utils/ErrorUtils.js +4 -40
  21. package/dist/src/utils/FlowAnalyze.js +8 -28
  22. package/dist/src/utils/TSNodeUtils.js +83 -0
  23. package/dist/src/utils/TranslationUtils.js +0 -13
  24. package/dist/src/utils/ts-estree-ast-types.js +0 -29
  25. package/dist/utils/DocblockUtils.js +4 -14
  26. package/dist/utils/DocblockUtils.js.flow +1 -1
  27. package/dist/utils/ErrorUtils.js +4 -40
  28. package/dist/utils/ErrorUtils.js.flow +6 -6
  29. package/dist/utils/FlowAnalyze.js +8 -28
  30. package/dist/utils/FlowAnalyze.js.flow +9 -4
  31. package/dist/utils/TSNodeUtils.js +83 -0
  32. package/dist/utils/TSNodeUtils.js.flow +108 -0
  33. package/dist/utils/TranslationUtils.js +0 -13
  34. package/dist/utils/TranslationUtils.js.flow +2 -2
  35. package/dist/utils/ts-estree-ast-types.js +0 -29
  36. package/dist/utils/ts-estree-ast-types.js.flow +697 -740
  37. package/package.json +10 -9
@@ -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 cloneJSDocCommentsToNewNode = // $FlowExpectedError[incompatible-type] - trust me this re-type is 100% safe
49
- _hermesTransform.cloneJSDocCommentsToNewNode;
50
- const makeCommentOwnLine = // $FlowExpectedError[incompatible-type] - trust me this re-type is 100% safe
51
- _hermesTransform.makeCommentOwnLine;
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[// $FlowExpectedError[prop-missing]
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); // $FlowExpectedError[prop-missing]
160
- // $FlowExpectedError[cannot-write]
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
- })(); // No variable found, it is not imported.
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
- }, // flow also exports `.cast`, `.isValid`, `.members` and `.getName` for enums
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: [// export function cast(value: number | null | undefined): Foo
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
- }, // export function isValid(value: number | null | undefined): value is Foo;
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
- }, // export function members(): IterableIterator<Foo>;
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
- typeParameters: {
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
- }, // export function getName(value: Foo): string;
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
- typeParameters: transform.TypeParameterInstantiation(node.typeParameters)
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
- superTypeParameters: transform.TypeParameterInstantiation(superClass == null ? void 0 : superClass.typeParameters),
1024
- typeParameters: node.typeParameters == null ? undefined : transform.TypeParameterDeclaration(node.typeParameters) // TODO - mixins??
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; // QualifiedTypeIdentifiers are types so cannot be handled without the intermediate variable so
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
- } // intentional fallthrough to the "value" handling
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
- } // intentional fallthrough to the "default" handling
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
- } // intentional fallthrough to the "default" handling
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 params = transform.ComponentTypeParameters(node.params, node.rest); // TS cannot support `renderType` so we always use ReactNode as the return type.
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
- typeParameters: undefined
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: 'VariableDeclarator',
1684
- loc: DUMMY_LOC,
1685
- declare: true,
1686
- id: transform.Identifier(node.id, true),
1687
- init: null
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
- typeParameters: {
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
- typeParameters: {
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
- typeParameters: {
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
- } // New AST format for `typeof import('module')`
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
- typeParameters: null
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
- typeParameters: {
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
- typeParameters: {
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
- typeParameters: {
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
- typeParameters: {
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
- typeParameters: {
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
- } // React special conversion:
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
- typeParameters: {
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
- typeParameters: {
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
- typeParameters: {
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
- typeParameters: undefined
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
- typeParameters: undefined
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
- typeParameters: {
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
- typeParameters: {
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
- typeParameters: undefined
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
- typeParameters: {
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
- typeParameters: {
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
- typeParameters: {
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
- typeParameters: {
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
- typeParameters: {
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
- typeParameters: {
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
- typeParameters: {
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
- typeParameters: transform.TypeParameterInstantiation(node.typeParameters)
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
- typeParameters: transform.TypeParameterInstantiation(node.typeParameters)
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
- typeParameters: transform.TypeParameterInstantiation(ex.typeParameters)
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
- } // we want to preserve the source order of the members
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
- typeParameters: {
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: [...remainingTypes.map(t => ({
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
- // flow has just one node for all object properties and relies upon the method flag
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
- // flow treats getters/setters as true property signatures (method === false)
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
- } // $FlowFixMe[incompatible-type] `computed` is set dynamically
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
- } // TS doesn't support optional index access so we have to wrap the object:
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
- typeParameters: {
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
- typeParameters: undefined
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
- typeParameters: undefined
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 // in: variance.has('in'),
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
- typeParameters: undefined
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); // TS cannot support `renderType` so we always use ReactNode as the return type.
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
- typeParameters: undefined
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]; // $FlowExpectedError[cannot-write]
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
  };