@@ -16,8 +16,22 @@ function isInType(path) {
16
16
}
17
17
}
18
18
19
+ function isTSExportableDeclaration ( node ) {
20
+ // all kinds of type exports that transpile to nothing
21
+ // exception is enums, since they transpile to JS values
22
+ return (
23
+ t . isTSInterfaceDeclaration ( node ) ||
24
+ t . isTSTypeAliasDeclaration ( node ) ||
25
+ t . isTSModuleDeclaration ( node ) ||
26
+ ( t . isVariableDeclaration ( node ) && node . declare ) ||
27
+ ( t . isClassDeclaration ( node ) && node . declare ) ||
28
+ t . isTSDeclareFunction ( node )
29
+ ) ;
30
+ }
31
+
19
32
interface State {
20
33
programPath: any ;
34
+ exportableTSNames: Set < string > ;
21
35
}
22
36
23
37
const PARSED_PARAMS = new WeakSet ( ) ;
@@ -40,6 +54,7 @@ export default declare((api, { jsxPragma = "React" }) => {
40
54
41
55
Program ( path , state : State ) {
42
56
state . programPath = path ;
57
+ state . exportableTSNames = new Set ( ) ;
43
58
44
59
const { file } = state ;
45
60
@@ -52,6 +67,32 @@ export default declare((api, { jsxPragma = "React" }) => {
52
67
}
53
68
}
54
69
70
+ // find exportable top level type declarations
71
+ for ( const stmt of path . get ( "body" ) ) {
72
+ if ( isTSExportableDeclaration ( stmt . node ) ) {
73
+ if ( stmt . node . id && stmt . node . id . name ) {
74
+ state . exportableTSNames . add ( stmt . node . id . name ) ;
75
+ } else if (
76
+ stmt . node . declarations &&
77
+ stmt . node . declarations . length > 0
78
+ ) {
79
+ for ( const declaration of stmt . node . declarations ) {
80
+ if ( declaration . id && declaration . id . name ) {
81
+ state . exportableTSNames . add ( declaration . id . name ) ;
82
+ }
83
+ }
84
+ }
85
+ } else if (
86
+ t . isExportNamedDeclaration ( stmt . node ) &&
87
+ stmt . node . specifiers . length === 0 &&
88
+ isTSExportableDeclaration ( stmt . node . declaration ) &&
89
+ stmt . node . declaration . id &&
90
+ stmt . node . declaration . id . name
91
+ ) {
92
+ state . exportableTSNames . add ( stmt . node . declaration . id . name ) ;
93
+ }
94
+ }
95
+
55
96
// remove type imports
56
97
for ( const stmt of path . get ( "body" ) ) {
57
98
if ( t . isImportDeclaration ( stmt ) ) {
@@ -94,6 +135,26 @@ export default declare((api, { jsxPragma = "React" }) => {
94
135
}
95
136
} ,
96
137
138
+ ExportNamedDeclaration ( path , { exportableTSNames } ) {
139
+ // remove export declaration if it's exporting only types
140
+ if (
141
+ path . node . specifiers . length > 0 &&
142
+ ! path . node . specifiers . find (
143
+ exportSpecifier =>
144
+ ! exportableTSNames . has ( exportSpecifier . local . name ) ,
145
+ )
146
+ ) {
147
+ path . remove ( ) ;
148
+ }
149
+ } ,
150
+
151
+ ExportSpecifier ( path , { exportableTSNames } ) {
152
+ // remove type exports
153
+ if ( exportableTSNames . has ( path . node . local . name ) ) {
154
+ path . remove ( ) ;
155
+ }
156
+ } ,
157
+
97
158
TSDeclareFunction ( path ) {
98
159
path . remove ( ) ;
99
160
} ,
0 commit comments