Skip to content

Commit ab4b779

Browse files
authored
prefer-export-from: Fix type-import being removed when using namespace import (#2771)
1 parent f6a281f commit ab4b779

File tree

4 files changed

+113
-4
lines changed

4 files changed

+113
-4
lines changed

rules/prefer-export-from.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -86,14 +86,14 @@ function getFixFunction({
8686
if (imported.name === NAMESPACE_SPECIFIER_NAME) {
8787
yield fixer.insertTextAfter(
8888
program,
89-
`\nexport * as ${exported.text} ${getSourceAndAssertionsText(importDeclaration, context)}`,
89+
`\nexport ${shouldExportAsType ? 'type ' : ''}* as ${exported.text} ${getSourceAndAssertionsText(importDeclaration, context)}`,
9090
);
9191
} else {
9292
let specifierText = exported.name === imported.name
9393
? exported.text
9494
: `${imported.text} as ${exported.text}`;
9595

96-
// Add an inline type specifier if the value is a type and the export deceleration is a value deceleration
96+
// Add an inline type specifier if the value is a type and the export declaration is a value declaration
9797
if (shouldExportAsType && (!exportDeclaration || exportDeclaration.exportKind !== 'type')) {
9898
specifierText = `type ${specifierText}`;
9999
}
@@ -116,7 +116,8 @@ function getFixFunction({
116116
}
117117
}
118118

119-
if (imported.variable.references.length === 1) {
119+
const importHasSideEffects = exported.isTypeExport && !imported.isTypeImport;
120+
if (imported.variable.references.length === 1 && !importHasSideEffects) {
120121
yield removeImportOrExport(imported.node, fixer, context);
121122
}
122123

test/prefer-export-from.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -474,6 +474,22 @@ test.snapshot({
474474
export {foo};
475475
export {bar} from './foo.json' assert { type: 'unknown' };
476476
`,
477+
outdent`
478+
import type * as X from 'foo';
479+
export { X };
480+
`,
481+
outdent`
482+
import * as X from 'foo';
483+
export type { X };
484+
`,
485+
outdent`
486+
import type * as X from 'foo';
487+
export type { X };
488+
`,
489+
outdent`
490+
import * as X from 'foo';
491+
export { X };
492+
`,
477493
],
478494
});
479495

test/snapshots/prefer-export-from.js.md

Lines changed: 93 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1871,7 +1871,7 @@ Generated by [AVA](https://avajs.dev).
18711871
| ^^^ Use \`export…from\` to re-export \`foo\`.␊
18721872
18731873
Output:␊
1874-
1 |␊
1874+
1 | import { foo } from 'foo';
18751875
2 |␊
18761876
3 | export {type foo} from 'foo';␊
18771877
`
@@ -2158,6 +2158,98 @@ Generated by [AVA](https://avajs.dev).
21582158
3 | export {bar, foo} from './foo.json' assert { type: 'unknown' };␊
21592159
`
21602160

2161+
## invalid(26): import type * as X from 'foo'; export { X };
2162+
2163+
> Input
2164+
2165+
`␊
2166+
1 | import type * as X from 'foo';␊
2167+
2 | export { X };␊
2168+
`
2169+
2170+
> Error 1/1
2171+
2172+
`␊
2173+
Message:␊
2174+
1 | import type * as X from 'foo';␊
2175+
> 2 | export { X };␊
2176+
| ^ Use \`export…from\` to re-export \`X\`.␊
2177+
2178+
Output:␊
2179+
1 |␊
2180+
2 |␊
2181+
3 | export type * as X from 'foo';␊
2182+
`
2183+
2184+
## invalid(27): import * as X from 'foo'; export type { X };
2185+
2186+
> Input
2187+
2188+
`␊
2189+
1 | import * as X from 'foo';␊
2190+
2 | export type { X };␊
2191+
`
2192+
2193+
> Error 1/1
2194+
2195+
`␊
2196+
Message:␊
2197+
1 | import * as X from 'foo';␊
2198+
> 2 | export type { X };␊
2199+
| ^ Use \`export…from\` to re-export \`X\`.␊
2200+
2201+
Output:␊
2202+
1 | import * as X from 'foo';␊
2203+
2 |␊
2204+
3 | export type * as X from 'foo';␊
2205+
`
2206+
2207+
## invalid(28): import type * as X from 'foo'; export type { X };
2208+
2209+
> Input
2210+
2211+
`␊
2212+
1 | import type * as X from 'foo';␊
2213+
2 | export type { X };␊
2214+
`
2215+
2216+
> Error 1/1
2217+
2218+
`␊
2219+
Message:␊
2220+
1 | import type * as X from 'foo';␊
2221+
> 2 | export type { X };␊
2222+
| ^ Use \`export…from\` to re-export \`X\`.␊
2223+
2224+
Output:␊
2225+
1 |␊
2226+
2 |␊
2227+
3 | export type * as X from 'foo';␊
2228+
`
2229+
2230+
## invalid(29): import * as X from 'foo'; export { X };
2231+
2232+
> Input
2233+
2234+
`␊
2235+
1 | import * as X from 'foo';␊
2236+
2 | export { X };␊
2237+
`
2238+
2239+
> Error 1/1
2240+
2241+
`␊
2242+
Message:␊
2243+
1 | import * as X from 'foo';␊
2244+
> 2 | export { X };␊
2245+
| ^ Use \`export…from\` to re-export \`X\`.␊
2246+
2247+
Output:␊
2248+
1 |␊
2249+
2 |␊
2250+
3 | export * as X from 'foo';␊
2251+
`
2252+
21612253
## invalid(1): import json from './foo.json' with { type: 'json' }; export default json;
21622254

21632255
> Input
156 Bytes
Binary file not shown.

0 commit comments

Comments
 (0)