fix(typescript): erase type exports (#9944)
* fix(typescript): erase type exports * use Set instead of array for tracking and checking TS type declarations * add a test for an interface exported before its declaration
This commit is contained in:
parent
3f0590de2a
commit
2080042808
@ -16,8 +16,22 @@ function isInType(path) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function isTSExportableDeclaration(node) {
|
||||||
|
// all kinds of type exports that transpile to nothing
|
||||||
|
// exception is enums, since they transpile to JS values
|
||||||
|
return (
|
||||||
|
t.isTSInterfaceDeclaration(node) ||
|
||||||
|
t.isTSTypeAliasDeclaration(node) ||
|
||||||
|
t.isTSModuleDeclaration(node) ||
|
||||||
|
(t.isVariableDeclaration(node) && node.declare) ||
|
||||||
|
(t.isClassDeclaration(node) && node.declare) ||
|
||||||
|
t.isTSDeclareFunction(node)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
interface State {
|
interface State {
|
||||||
programPath: any;
|
programPath: any;
|
||||||
|
exportableTSNames: Set<string>;
|
||||||
}
|
}
|
||||||
|
|
||||||
const PARSED_PARAMS = new WeakSet();
|
const PARSED_PARAMS = new WeakSet();
|
||||||
@ -40,6 +54,7 @@ export default declare((api, { jsxPragma = "React" }) => {
|
|||||||
|
|
||||||
Program(path, state: State) {
|
Program(path, state: State) {
|
||||||
state.programPath = path;
|
state.programPath = path;
|
||||||
|
state.exportableTSNames = new Set();
|
||||||
|
|
||||||
const { file } = state;
|
const { file } = state;
|
||||||
|
|
||||||
@ -52,6 +67,32 @@ export default declare((api, { jsxPragma = "React" }) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// find exportable top level type declarations
|
||||||
|
for (const stmt of path.get("body")) {
|
||||||
|
if (isTSExportableDeclaration(stmt.node)) {
|
||||||
|
if (stmt.node.id && stmt.node.id.name) {
|
||||||
|
state.exportableTSNames.add(stmt.node.id.name);
|
||||||
|
} else if (
|
||||||
|
stmt.node.declarations &&
|
||||||
|
stmt.node.declarations.length > 0
|
||||||
|
) {
|
||||||
|
for (const declaration of stmt.node.declarations) {
|
||||||
|
if (declaration.id && declaration.id.name) {
|
||||||
|
state.exportableTSNames.add(declaration.id.name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (
|
||||||
|
t.isExportNamedDeclaration(stmt.node) &&
|
||||||
|
stmt.node.specifiers.length === 0 &&
|
||||||
|
isTSExportableDeclaration(stmt.node.declaration) &&
|
||||||
|
stmt.node.declaration.id &&
|
||||||
|
stmt.node.declaration.id.name
|
||||||
|
) {
|
||||||
|
state.exportableTSNames.add(stmt.node.declaration.id.name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// remove type imports
|
// remove type imports
|
||||||
for (const stmt of path.get("body")) {
|
for (const stmt of path.get("body")) {
|
||||||
if (t.isImportDeclaration(stmt)) {
|
if (t.isImportDeclaration(stmt)) {
|
||||||
@ -94,6 +135,26 @@ export default declare((api, { jsxPragma = "React" }) => {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
ExportNamedDeclaration(path, { exportableTSNames }) {
|
||||||
|
// remove export declaration if it's exporting only types
|
||||||
|
if (
|
||||||
|
path.node.specifiers.length > 0 &&
|
||||||
|
!path.node.specifiers.find(
|
||||||
|
exportSpecifier =>
|
||||||
|
!exportableTSNames.has(exportSpecifier.local.name),
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
path.remove();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
ExportSpecifier(path, { exportableTSNames }) {
|
||||||
|
// remove type exports
|
||||||
|
if (exportableTSNames.has(path.node.local.name)) {
|
||||||
|
path.remove();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
TSDeclareFunction(path) {
|
TSDeclareFunction(path) {
|
||||||
path.remove();
|
path.remove();
|
||||||
},
|
},
|
||||||
|
|||||||
@ -8,3 +8,40 @@ declare namespace N {}
|
|||||||
export interface I {}
|
export interface I {}
|
||||||
export type T = number;
|
export type T = number;
|
||||||
export class C2 {}
|
export class C2 {}
|
||||||
|
|
||||||
|
export { x, f, E, C }; // only E
|
||||||
|
export { M, N, I as I1, T as T1 }; // everything removed
|
||||||
|
export {
|
||||||
|
x as x2,
|
||||||
|
f as f2,
|
||||||
|
C as CC2,
|
||||||
|
E as E2,
|
||||||
|
M as M2,
|
||||||
|
N as N2,
|
||||||
|
I as I2,
|
||||||
|
T as T2,
|
||||||
|
C2 as C3
|
||||||
|
}; // only E and C2
|
||||||
|
|
||||||
|
interface II2 {}
|
||||||
|
type AA = {};
|
||||||
|
enum BB {
|
||||||
|
K
|
||||||
|
}
|
||||||
|
enum BB {
|
||||||
|
L = "LL"
|
||||||
|
}
|
||||||
|
export { II2, AA, BB }; // only BB
|
||||||
|
export { II2 as II3, AA as AA2 }; // everything removed
|
||||||
|
export { BB as BB1 }; // as-is
|
||||||
|
|
||||||
|
interface II3 {}
|
||||||
|
type AA2 = {};
|
||||||
|
enum BB2 {}
|
||||||
|
function foo() {}
|
||||||
|
export { II3 as default, AA2 as A, BB2 as BB3, foo }; // only BB2 and foo
|
||||||
|
|
||||||
|
// export an interface before declaration
|
||||||
|
export { Bar } // everything removed
|
||||||
|
export { Bar as Bar2, C2 as C4 } // only C4
|
||||||
|
interface Bar {}
|
||||||
|
|||||||
@ -1 +1,32 @@
|
|||||||
export class C2 {}
|
export class C2 {}
|
||||||
|
export { E }; // only E
|
||||||
|
|
||||||
|
// everything removed
|
||||||
|
export { E as E2, C2 as C3 }; // only E and C2
|
||||||
|
|
||||||
|
var BB;
|
||||||
|
|
||||||
|
(function (BB) {
|
||||||
|
BB[BB["K"] = 0] = "K";
|
||||||
|
})(BB || (BB = {}));
|
||||||
|
|
||||||
|
(function (BB) {
|
||||||
|
BB["L"] = "LL";
|
||||||
|
})(BB || (BB = {}));
|
||||||
|
|
||||||
|
export { BB }; // only BB
|
||||||
|
|
||||||
|
// everything removed
|
||||||
|
export { BB as BB1 }; // as-is
|
||||||
|
|
||||||
|
var BB2;
|
||||||
|
|
||||||
|
(function (BB2) {})(BB2 || (BB2 = {}));
|
||||||
|
|
||||||
|
function foo() {}
|
||||||
|
|
||||||
|
export { BB2 as BB3, foo }; // only BB2 and foo
|
||||||
|
// export an interface before declaration
|
||||||
|
|
||||||
|
// everything removed
|
||||||
|
export { C2 as C4 }; // only C4
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user