flow-api-translator 0.15.1 → 0.17.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.
@@ -16,10 +16,10 @@ exports.flowDefToTSDef = flowDefToTSDef;
16
16
 
17
17
  var FlowESTree = _interopRequireWildcard(require("hermes-estree"));
18
18
 
19
- var _hermesTransform = require("hermes-transform");
20
-
21
19
  var TSESTree = _interopRequireWildcard(require("./utils/ts-estree-ast-types"));
22
20
 
21
+ var _hermesTransform = require("hermes-transform");
22
+
23
23
  var _ErrorUtils = require("./utils/ErrorUtils");
24
24
 
25
25
  var _DocblockUtils = require("./utils/DocblockUtils");
@@ -30,6 +30,11 @@ function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "functio
30
30
 
31
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
32
 
33
+ function constructFlowNode(node) {
34
+ // $FlowFixMe[prop-missing]
35
+ return node;
36
+ }
37
+
33
38
  const cloneJSDocCommentsToNewNode = // $FlowExpectedError[incompatible-cast] - trust me this re-type is 100% safe
34
39
  _hermesTransform.cloneJSDocCommentsToNewNode;
35
40
  const makeCommentOwnLine = // $FlowExpectedError[incompatible-cast] - trust me this re-type is 100% safe
@@ -40,7 +45,19 @@ function isValidReactImportOrGlobal(id) {
40
45
  return VALID_REACT_IMPORTS.has(id.name) || id.name.startsWith('React$');
41
46
  }
42
47
 
43
- let shouldAddReactImport = null;
48
+ let shouldAddReactImport = null; // Returns appropriate Identifier for `React` import.
49
+ // If a global is in use, set a flag to indicate that we should add the import.
50
+
51
+ function getReactIdentifier(hasReactImport) {
52
+ if (shouldAddReactImport !== false) {
53
+ shouldAddReactImport = !hasReactImport;
54
+ }
55
+
56
+ return {
57
+ type: 'Identifier',
58
+ name: `React`
59
+ };
60
+ }
44
61
 
45
62
  function flowDefToTSDef(originalCode, ast, scopeManager, opts) {
46
63
  const tsBody = [];
@@ -178,10 +195,10 @@ const getTransforms = (originalCode, scopeManager, opts) => {
178
195
  return globalScope;
179
196
  })();
180
197
 
181
- function isReactImport(id) {
198
+ function isReactImport(scopeNode, name) {
182
199
  let currentScope = (() => {
183
200
  let scope = null;
184
- let node = id;
201
+ let node = scopeNode;
185
202
 
186
203
  while (!scope && node) {
187
204
  scope = scopeManager.acquire(node, true);
@@ -198,7 +215,7 @@ const getTransforms = (originalCode, scopeManager, opts) => {
198
215
  const variableDef = (() => {
199
216
  while (currentScope != null) {
200
217
  for (const variable of currentScope.variables) {
201
- if (variable.defs.length && variable.name === id.name) {
218
+ if (variable.defs.length && variable.name === name) {
202
219
  return variable;
203
220
  }
204
221
  }
@@ -230,7 +247,7 @@ const getTransforms = (originalCode, scopeManager, opts) => {
230
247
 
231
248
  case 'ImplicitGlobalVariable':
232
249
  {
233
- return VALID_REACT_IMPORTS.has(id.name);
250
+ return VALID_REACT_IMPORTS.has(name);
234
251
  }
235
252
  // TODO Handle:
236
253
  // const React = require('react');
@@ -616,7 +633,22 @@ const getTransforms = (originalCode, scopeManager, opts) => {
616
633
  return transform.VoidTypeAnnotation(node);
617
634
 
618
635
  case 'TypePredicate':
619
- return unsupportedAnnotation(node, node.type);
636
+ return transform.TypePredicateAnnotation(node);
637
+
638
+ case 'ConditionalTypeAnnotation':
639
+ return transform.ConditionalTypeAnnotation(node);
640
+
641
+ case 'InferTypeAnnotation':
642
+ return transform.InferTypeAnnotation(node);
643
+
644
+ case 'KeyofTypeAnnotation':
645
+ return transform.KeyofTypeAnnotation(node);
646
+
647
+ case 'TypeOperator':
648
+ return transform.TypeOperator(node);
649
+
650
+ case 'ComponentTypeAnnotation':
651
+ return transform.ComponentTypeAnnotation(node);
620
652
 
621
653
  default:
622
654
  throw unexpectedTranslationError(node, `Unhandled type ${node.type}`);
@@ -897,6 +929,21 @@ const getTransforms = (originalCode, scopeManager, opts) => {
897
929
  exportKind: 'value'
898
930
  }];
899
931
  }
932
+ // TS doesn't support direct default export for declare'd functions
933
+
934
+ case 'DeclareComponent':
935
+ {
936
+ const functionDecl = transform.DeclareComponent(declaration);
937
+ const name = declaration.id.name;
938
+ return [functionDecl, {
939
+ type: 'ExportDefaultDeclaration',
940
+ declaration: {
941
+ type: 'Identifier',
942
+ name
943
+ },
944
+ exportKind: 'value'
945
+ }];
946
+ }
900
947
  // Flow's declare export default Identifier is ambiguous.
901
948
  // the Identifier might reference a type, or it might reference a value
902
949
  // - If it's a value, then that's all good, TS supports that.
@@ -1024,6 +1071,12 @@ const getTransforms = (originalCode, scopeManager, opts) => {
1024
1071
  exportKind: 'value'
1025
1072
  }];
1026
1073
 
1074
+ case 'DeclareComponent':
1075
+ return [{
1076
+ declaration: transform.DeclareComponent(node.declaration),
1077
+ exportKind: 'value'
1078
+ }];
1079
+
1027
1080
  case 'DeclareFunction':
1028
1081
  return [{
1029
1082
  declaration: transform.DeclareFunction(node.declaration),
@@ -1092,6 +1145,113 @@ const getTransforms = (originalCode, scopeManager, opts) => {
1092
1145
  }
1093
1146
  },
1094
1147
 
1148
+ DeclareComponent(node) {
1149
+ const id = transform.Identifier(node.id, false);
1150
+ const typeParameters = node.typeParameters == null ? undefined : transform.TypeParameterDeclaration(node.typeParameters);
1151
+ const params = transform.ComponentTypeParameters(node.params, node.rest); // TS cannot support `renderType` so we always use ReactNode as the return type.
1152
+
1153
+ const hasReactImport = isReactImport(node, 'React');
1154
+ const returnType = {
1155
+ type: 'TSTypeAnnotation',
1156
+ // If no rendersType we assume its ReactNode type.
1157
+ typeAnnotation: {
1158
+ type: 'TSTypeReference',
1159
+ typeName: {
1160
+ type: 'TSQualifiedName',
1161
+ left: getReactIdentifier(hasReactImport),
1162
+ right: {
1163
+ type: 'Identifier',
1164
+ name: `ReactNode`
1165
+ }
1166
+ },
1167
+ typeParameters: undefined
1168
+ }
1169
+ };
1170
+ return {
1171
+ type: 'TSDeclareFunction',
1172
+ async: false,
1173
+ body: undefined,
1174
+ declare: true,
1175
+ expression: false,
1176
+ generator: false,
1177
+ id: {
1178
+ type: 'Identifier',
1179
+ name: id.name
1180
+ },
1181
+ params,
1182
+ returnType: returnType,
1183
+ typeParameters: typeParameters
1184
+ };
1185
+ },
1186
+
1187
+ ComponentTypeParameters(params, rest) {
1188
+ if (params.length === 0 && rest != null) {
1189
+ return [{
1190
+ type: 'Identifier',
1191
+ name: 'props',
1192
+ typeAnnotation: {
1193
+ type: 'TSTypeAnnotation',
1194
+ typeAnnotation: transformTypeAnnotationType(rest.typeAnnotation)
1195
+ },
1196
+ optional: false
1197
+ }];
1198
+ }
1199
+
1200
+ const flowPropsType = [];
1201
+
1202
+ if (rest != null) {
1203
+ flowPropsType.push(constructFlowNode({
1204
+ type: 'ObjectTypeSpreadProperty',
1205
+ argument: rest.typeAnnotation,
1206
+ range: rest.range,
1207
+ loc: rest.loc
1208
+ }));
1209
+ }
1210
+
1211
+ for (let i = 0; i < params.length; i++) {
1212
+ var _param$name;
1213
+
1214
+ const param = params[i];
1215
+ flowPropsType.push(constructFlowNode({
1216
+ type: 'ObjectTypeProperty',
1217
+ kind: 'init',
1218
+ method: false,
1219
+ optional: param.optional,
1220
+ variance: null,
1221
+ proto: false,
1222
+ static: false,
1223
+ key: (_param$name = param.name) != null ? _param$name : constructFlowNode({
1224
+ type: 'Identifier',
1225
+ name: `$$PARAM_${i}$$`,
1226
+ optional: false,
1227
+ typeAnnotation: null
1228
+ }),
1229
+ value: param.typeAnnotation,
1230
+ range: param.range,
1231
+ loc: param.loc
1232
+ }));
1233
+ }
1234
+
1235
+ const tsPropsObjectType = transform.ObjectTypeAnnotation(constructFlowNode({
1236
+ type: 'ObjectTypeAnnotation',
1237
+ inexact: false,
1238
+ exact: true,
1239
+ properties: flowPropsType,
1240
+ indexers: [],
1241
+ callProperties: [],
1242
+ internalSlots: []
1243
+ }));
1244
+ return [{
1245
+ type: 'Identifier',
1246
+ name: 'props',
1247
+ typeAnnotation: {
1248
+ type: 'TSTypeAnnotation',
1249
+ typeAnnotation: tsPropsObjectType
1250
+ },
1251
+ optional: false
1252
+ }];
1253
+ },
1254
+
1095
1255
  DeclareFunction(node) {
1096
1256
  // the function information is stored as an annotation on the ID...
1097
1257
  const id = transform.Identifier(node.id, false);
@@ -1483,7 +1643,7 @@ const getTransforms = (originalCode, scopeManager, opts) => {
1483
1643
  return {
1484
1644
  type: 'TSImportType',
1485
1645
  isTypeOf: true,
1486
- parameter: moduleName,
1646
+ argument: moduleName,
1487
1647
  qualifier: null,
1488
1648
  typeParameters: null
1489
1649
  };
@@ -1589,6 +1749,36 @@ const getTransforms = (originalCode, scopeManager, opts) => {
1589
1749
  };
1590
1750
  }
1591
1751
 
1752
+ case '$ReadOnlyMap':
1753
+ {
1754
+ return {
1755
+ type: 'TSTypeReference',
1756
+ typeName: {
1757
+ type: 'Identifier',
1758
+ name: 'ReadonlyMap'
1759
+ },
1760
+ typeParameters: {
1761
+ type: 'TSTypeParameterInstantiation',
1762
+ params: assertHasExactlyNTypeParameters(1)
1763
+ }
1764
+ };
1765
+ }
1766
+
1767
+ case '$ReadOnlySet':
1768
+ {
1769
+ return {
1770
+ type: 'TSTypeReference',
1771
+ typeName: {
1772
+ type: 'Identifier',
1773
+ name: 'ReadonlySet'
1774
+ },
1775
+ typeParameters: {
1776
+ type: 'TSTypeParameterInstantiation',
1777
+ params: assertHasExactlyNTypeParameters(1)
1778
+ }
1779
+ };
1780
+ }
1781
+
1592
1782
  case '$Values':
1593
1783
  {
1594
1784
  // `$Values<T>` => `T[keyof T]`
@@ -1642,22 +1832,9 @@ const getTransforms = (originalCode, scopeManager, opts) => {
1642
1832
 
1643
1833
 
1644
1834
  const validReactImportOrGlobal = isValidReactImportOrGlobal(baseId);
1645
- const reactImport = isReactImport(baseId);
1646
-
1647
- if (validReactImportOrGlobal || reactImport) {
1648
- // Returns appropriate Identifier for `React` import.
1649
- // If a global is in use, set a flag to indicate that we should add the import.
1650
- const getReactIdentifier = () => {
1651
- if (shouldAddReactImport !== false) {
1652
- shouldAddReactImport = !reactImport;
1653
- }
1654
-
1655
- return {
1656
- type: 'Identifier',
1657
- name: `React`
1658
- };
1659
- };
1835
+ const hasReactImport = isReactImport(baseId, baseId.name);
1660
1836
 
1837
+ if (validReactImportOrGlobal || hasReactImport) {
1661
1838
  switch (fullTypeName) {
1662
1839
  // TODO: In flow this is `ChildrenArray<T> = T | $ReadOnlyArray<ChildrenArray<T>>`.
1663
1840
  // The recursive nature of it is rarely needed, so we're simplifying this for now
@@ -1706,7 +1883,7 @@ const getTransforms = (originalCode, scopeManager, opts) => {
1706
1883
  type: 'TSTypeReference',
1707
1884
  typeName: {
1708
1885
  type: 'TSQualifiedName',
1709
- left: getReactIdentifier(),
1886
+ left: getReactIdentifier(hasReactImport),
1710
1887
  right: {
1711
1888
  type: 'Identifier',
1712
1889
  name: 'Component'
@@ -1727,7 +1904,7 @@ const getTransforms = (originalCode, scopeManager, opts) => {
1727
1904
  type: 'TSTypeReference',
1728
1905
  typeName: {
1729
1906
  type: 'TSQualifiedName',
1730
- left: getReactIdentifier(),
1907
+ left: getReactIdentifier(hasReactImport),
1731
1908
  right: {
1732
1909
  type: 'Identifier',
1733
1910
  name: `Context`
@@ -1748,7 +1925,7 @@ const getTransforms = (originalCode, scopeManager, opts) => {
1748
1925
  type: 'TSTypeReference',
1749
1926
  typeName: {
1750
1927
  type: 'TSQualifiedName',
1751
- left: getReactIdentifier(),
1928
+ left: getReactIdentifier(hasReactImport),
1752
1929
  right: {
1753
1930
  type: 'Identifier',
1754
1931
  name: 'Key'
@@ -1766,7 +1943,7 @@ const getTransforms = (originalCode, scopeManager, opts) => {
1766
1943
  type: 'TSTypeReference',
1767
1944
  typeName: {
1768
1945
  type: 'TSQualifiedName',
1769
- left: getReactIdentifier(),
1946
+ left: getReactIdentifier(hasReactImport),
1770
1947
  right: {
1771
1948
  type: 'Identifier',
1772
1949
  name: `ElementType`
@@ -1785,7 +1962,7 @@ const getTransforms = (originalCode, scopeManager, opts) => {
1785
1962
  type: 'TSTypeReference',
1786
1963
  typeName: {
1787
1964
  type: 'TSQualifiedName',
1788
- left: getReactIdentifier(),
1965
+ left: getReactIdentifier(hasReactImport),
1789
1966
  right: {
1790
1967
  type: 'Identifier',
1791
1968
  name: `ReactNode`
@@ -1803,7 +1980,7 @@ const getTransforms = (originalCode, scopeManager, opts) => {
1803
1980
  type: 'TSTypeReference',
1804
1981
  typeName: {
1805
1982
  type: 'TSQualifiedName',
1806
- left: getReactIdentifier(),
1983
+ left: getReactIdentifier(hasReactImport),
1807
1984
  right: {
1808
1985
  type: 'Identifier',
1809
1986
  name: `ReactElement`
@@ -1824,7 +2001,7 @@ const getTransforms = (originalCode, scopeManager, opts) => {
1824
2001
  type: 'TSTypeReference',
1825
2002
  typeName: {
1826
2003
  type: 'TSQualifiedName',
1827
- left: getReactIdentifier(),
2004
+ left: getReactIdentifier(hasReactImport),
1828
2005
  right: {
1829
2006
  type: 'Identifier',
1830
2007
  name: `ElementRef`
@@ -1845,7 +2022,7 @@ const getTransforms = (originalCode, scopeManager, opts) => {
1845
2022
  type: 'TSTypeReference',
1846
2023
  typeName: {
1847
2024
  type: 'TSQualifiedName',
1848
- left: getReactIdentifier(),
2025
+ left: getReactIdentifier(hasReactImport),
1849
2026
  right: {
1850
2027
  type: 'Identifier',
1851
2028
  name: `Fragment`
@@ -1884,7 +2061,7 @@ const getTransforms = (originalCode, scopeManager, opts) => {
1884
2061
  type: 'TSTypeReference',
1885
2062
  typeName: {
1886
2063
  type: 'TSQualifiedName',
1887
- left: getReactIdentifier(),
2064
+ left: getReactIdentifier(hasReactImport),
1888
2065
  right: {
1889
2066
  type: 'Identifier',
1890
2067
  name: 'ComponentType'
@@ -1949,7 +2126,7 @@ const getTransforms = (originalCode, scopeManager, opts) => {
1949
2126
  type: 'TSTypeReference',
1950
2127
  typeName: {
1951
2128
  type: 'TSQualifiedName',
1952
- left: getReactIdentifier(),
2129
+ left: getReactIdentifier(hasReactImport),
1953
2130
  right: {
1954
2131
  type: 'Identifier',
1955
2132
  name: 'ComponentType'
@@ -1971,7 +2148,7 @@ const getTransforms = (originalCode, scopeManager, opts) => {
1971
2148
  type: 'TSTypeReference',
1972
2149
  typeName: {
1973
2150
  type: 'TSQualifiedName',
1974
- left: getReactIdentifier(),
2151
+ left: getReactIdentifier(hasReactImport),
1975
2152
  right: {
1976
2153
  type: 'Identifier',
1977
2154
  name: 'ComponentProps'
@@ -2009,7 +2186,7 @@ const getTransforms = (originalCode, scopeManager, opts) => {
2009
2186
  type: 'TSTypeReference',
2010
2187
  typeName: {
2011
2188
  type: 'TSQualifiedName',
2012
- left: getReactIdentifier(),
2189
+ left: getReactIdentifier(hasReactImport),
2013
2190
  right: {
2014
2191
  type: 'Identifier',
2015
2192
  name: `ComponentProps`
@@ -2042,7 +2219,7 @@ const getTransforms = (originalCode, scopeManager, opts) => {
2042
2219
  type: 'TSTypeReference',
2043
2220
  typeName: {
2044
2221
  type: 'TSQualifiedName',
2045
- left: getReactIdentifier(),
2222
+ left: getReactIdentifier(hasReactImport),
2046
2223
  right: {
2047
2224
  type: 'Identifier',
2048
2225
  name: 'Ref'
@@ -2277,10 +2454,35 @@ const getTransforms = (originalCode, scopeManager, opts) => {
2277
2454
  },
2278
2455
 
2279
2456
  ObjectTypeAnnotation(node) {
2280
- // we want to preserve the source order of the members
2457
+ if (node.properties.length === 1 && node.properties[0].type === 'ObjectTypeMappedTypeProperty') {
2458
+ var _prop$variance;
2459
+
2460
+ // Mapped Object Object types must not have other object properties.
2461
+ const prop = node.properties[0];
2462
+ const tsProp = {
2463
+ type: 'TSMappedType',
2464
+ typeParameter: {
2465
+ type: 'TSTypeParameter',
2466
+ name: {
2467
+ type: 'Identifier',
2468
+ name: prop.keyTparam.name
2469
+ },
2470
+ constraint: transformTypeAnnotationType(prop.sourceType),
2471
+ in: false,
2472
+ out: false
2473
+ },
2474
+ readonly: ((_prop$variance = prop.variance) == null ? void 0 : _prop$variance.kind) === 'plus',
2475
+ optional: prop.optional === 'Optional',
2476
+ typeAnnotation: transformTypeAnnotationType(prop.propType),
2477
+ nameType: null
2478
+ };
2479
+ return tsProp;
2480
+ } // we want to preserve the source order of the members
2281
2481
  // unfortunately flow has unordered properties storing things
2282
2482
  // so store all elements with their start index and sort the
2283
2483
  // list afterward
2484
+
2485
+
2284
2486
  const members = [];
2285
2487
 
2286
2488
  for (const callProp of node.callProperties) {
@@ -2316,8 +2518,7 @@ const getTransforms = (originalCode, scopeManager, opts) => {
2316
2518
  }
2317
2519
 
2318
2520
  if (property.type === 'ObjectTypeMappedTypeProperty') {
2319
- // TODO - Support mapped types
2320
- return unsupportedAnnotation(property, 'object type with mapped type property');
2521
+ return unsupportedAnnotation(property, 'object type with mapped type property along with other properties');
2321
2522
  }
2322
2523
 
2323
2524
  members.push({
@@ -2784,6 +2985,93 @@ const getTransforms = (originalCode, scopeManager, opts) => {
2784
2985
  return {
2785
2986
  type: 'TSVoidKeyword'
2786
2987
  };
2988
+ },
2989
+
2990
+ ConditionalTypeAnnotation(node) {
2991
+ return {
2992
+ type: 'TSConditionalType',
2993
+ checkType: transformTypeAnnotationType(node.checkType),
2994
+ extendsType: transformTypeAnnotationType(node.extendsType),
2995
+ trueType: transformTypeAnnotationType(node.trueType),
2996
+ falseType: transformTypeAnnotationType(node.falseType)
2997
+ };
2998
+ },
2999
+
3000
+ TypePredicateAnnotation(node) {
3001
+ return {
3002
+ type: 'TSTypePredicate',
3003
+ asserts: node.asserts,
3004
+ parameterName: transform.Identifier(node.parameterName, false),
3005
+ typeAnnotation: node.typeAnnotation && {
3006
+ type: 'TSTypeAnnotation',
3007
+ typeAnnotation: transformTypeAnnotationType(node.typeAnnotation)
3008
+ }
3009
+ };
3010
+ },
3011
+
3012
+ InferTypeAnnotation(node) {
3013
+ return {
3014
+ type: 'TSInferType',
3015
+ typeParameter: transform.TypeParameter(node.typeParameter)
3016
+ };
3017
+ },
3018
+
3019
+ KeyofTypeAnnotation(node) {
3020
+ return {
3021
+ type: 'TSTypeOperator',
3022
+ operator: 'keyof',
3023
+ typeAnnotation: transformTypeAnnotationType(node.argument)
3024
+ };
3025
+ },
3026
+
3027
+ TypeOperator(node) {
3028
+ switch (node.operator) {
3029
+ case 'renders':
3030
+ {
3031
+ const hasReactImport = isReactImport(node, 'React');
3032
+ return {
3033
+ type: 'TSTypeReference',
3034
+ typeName: {
3035
+ type: 'TSQualifiedName',
3036
+ left: getReactIdentifier(hasReactImport),
3037
+ right: {
3038
+ type: 'Identifier',
3039
+ name: `ReactNode`
3040
+ }
3041
+ },
3042
+ typeParameters: undefined
3043
+ };
3044
+ }
3045
+ }
3046
+ },
3047
+
3048
+ ComponentTypeAnnotation(node) {
3049
+ const typeParameters = node.typeParameters == null ? undefined : transform.TypeParameterDeclaration(node.typeParameters);
3050
+ const params = transform.ComponentTypeParameters(node.params, node.rest); // TS cannot support `renderType` so we always use ReactNode as the return type.
3051
+
3052
+ const hasReactImport = isReactImport(node, 'React');
3053
+ const returnType = {
3054
+ type: 'TSTypeAnnotation',
3055
+ // If no rendersType we assume its ReactNode type.
3056
+ typeAnnotation: {
3057
+ type: 'TSTypeReference',
3058
+ typeName: {
3059
+ type: 'TSQualifiedName',
3060
+ left: getReactIdentifier(hasReactImport),
3061
+ right: {
3062
+ type: 'Identifier',
3063
+ name: `ReactNode`
3064
+ }
3065
+ },
3066
+ typeParameters: undefined
3067
+ }
3068
+ };
3069
+ return {
3070
+ type: 'TSFunctionType',
3071
+ typeParameters,
3072
+ params,
3073
+ returnType
3074
+ };
2787
3075
  }
2788
3076
 
2789
3077
  }; // wrap each transform so that we automatically preserve jsdoc comments