Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion src/compiler/transformers/ts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2301,7 +2301,10 @@ export function transformTypeScript(context: TransformationContext): Transformer
}
else {
// Elide named imports if all of its import specifiers are elided and settings allow.
const allowEmpty = compilerOptions.verbatimModuleSyntax;
// When a default import exists, avoid keeping empty named braces under verbatimModuleSyntax.
const parentImportClause = node.parent as ImportClause | undefined;
const defaultBindingPresent = !!parentImportClause?.name;
const allowEmpty = compilerOptions.verbatimModuleSyntax && !defaultBindingPresent;
const elements = visitNodes(node.elements, visitImportSpecifier, isImportSpecifier);
return allowEmpty || some(elements) ? factory.updateNamedImports(node, elements) : undefined;
}
Expand Down
58 changes: 58 additions & 0 deletions tests/baselines/reference/verbatimModuleSyntaxEmptyNamedImport.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
//// [tests/cases/compiler/verbatimModuleSyntaxEmptyNamedImport.ts] ////

//// [verbatimModuleSyntaxEmptyNamedImport_module.ts]
export const ValueExport = 0;
export type TypeOnlyExport = number;
const DefaultExport = class {};
export default DefaultExport;

//// [verbatimModuleSyntaxEmptyNamedImport_module.d.ts]
declare module "verbatimModuleSyntaxEmptyNamedImport_module";

//// [verbatimModuleSyntaxEmptyNamedImport_test.ts]
import DefaultExportA, {
type TypeOnlyExport as TypeOnlyExportA,
} from "verbatimModuleSyntaxEmptyNamedImport_module";
import DefaultExportB, {
type TypeOnlyExport as TypeOnlyExportB,
ValueExport as ValueExportB,
} from "verbatimModuleSyntaxEmptyNamedImport_module";
import DefaultExportC, {
ValueExport as RenamedValueExportC,
} from "verbatimModuleSyntaxEmptyNamedImport_module";
import DefaultExportD from "verbatimModuleSyntaxEmptyNamedImport_module";
import { type TypeOnlyExport as RenamedTypeOnlyExportE } from "verbatimModuleSyntaxEmptyNamedImport_module";
import { ValueExport as RenamedValueExportF } from "verbatimModuleSyntaxEmptyNamedImport_module";
import * as NamespaceImportG from "verbatimModuleSyntaxEmptyNamedImport_module";

new DefaultExportA();
new DefaultExportB();
new DefaultExportC();
new DefaultExportD();
console.log(ValueExportB);
console.log(RenamedValueExportC);
console.log(RenamedValueExportF);
console.log(NamespaceImportG.ValueExport);


//// [verbatimModuleSyntaxEmptyNamedImport_module.js]
export const ValueExport = 0;
const DefaultExport = class {
};
export default DefaultExport;
//// [verbatimModuleSyntaxEmptyNamedImport_test.js]
import DefaultExportA from "verbatimModuleSyntaxEmptyNamedImport_module";
import DefaultExportB, { ValueExport as ValueExportB, } from "verbatimModuleSyntaxEmptyNamedImport_module";
import DefaultExportC, { ValueExport as RenamedValueExportC, } from "verbatimModuleSyntaxEmptyNamedImport_module";
import DefaultExportD from "verbatimModuleSyntaxEmptyNamedImport_module";
import {} from "verbatimModuleSyntaxEmptyNamedImport_module";
import { ValueExport as RenamedValueExportF } from "verbatimModuleSyntaxEmptyNamedImport_module";
import * as NamespaceImportG from "verbatimModuleSyntaxEmptyNamedImport_module";
new DefaultExportA();
new DefaultExportB();
new DefaultExportC();
new DefaultExportD();
console.log(ValueExportB);
console.log(RenamedValueExportC);
console.log(RenamedValueExportF);
console.log(NamespaceImportG.ValueExport);
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
//// [tests/cases/compiler/verbatimModuleSyntaxEmptyNamedImport.ts] ////

=== verbatimModuleSyntaxEmptyNamedImport_module.ts ===
export const ValueExport = 0;
>ValueExport : Symbol(ValueExport, Decl(verbatimModuleSyntaxEmptyNamedImport_module.ts, 0, 12))

export type TypeOnlyExport = number;
>TypeOnlyExport : Symbol(TypeOnlyExport, Decl(verbatimModuleSyntaxEmptyNamedImport_module.ts, 0, 29))

const DefaultExport = class {};
>DefaultExport : Symbol(DefaultExport, Decl(verbatimModuleSyntaxEmptyNamedImport_module.ts, 2, 5))

export default DefaultExport;
>DefaultExport : Symbol(DefaultExport, Decl(verbatimModuleSyntaxEmptyNamedImport_module.ts, 2, 5))

=== verbatimModuleSyntaxEmptyNamedImport_module.d.ts ===
declare module "verbatimModuleSyntaxEmptyNamedImport_module";
>"verbatimModuleSyntaxEmptyNamedImport_module" : Symbol("verbatimModuleSyntaxEmptyNamedImport_module", Decl(verbatimModuleSyntaxEmptyNamedImport_module.d.ts, 0, 0))

=== verbatimModuleSyntaxEmptyNamedImport_test.ts ===
import DefaultExportA, {
>DefaultExportA : Symbol(DefaultExportA, Decl(verbatimModuleSyntaxEmptyNamedImport_test.ts, 0, 6))

type TypeOnlyExport as TypeOnlyExportA,
>TypeOnlyExport : Symbol(DefaultExportA, Decl(verbatimModuleSyntaxEmptyNamedImport_module.d.ts, 0, 0))
>TypeOnlyExportA : Symbol(TypeOnlyExportA, Decl(verbatimModuleSyntaxEmptyNamedImport_test.ts, 0, 24))

} from "verbatimModuleSyntaxEmptyNamedImport_module";
import DefaultExportB, {
>DefaultExportB : Symbol(DefaultExportB, Decl(verbatimModuleSyntaxEmptyNamedImport_test.ts, 3, 6))

type TypeOnlyExport as TypeOnlyExportB,
>TypeOnlyExport : Symbol(DefaultExportA, Decl(verbatimModuleSyntaxEmptyNamedImport_module.d.ts, 0, 0))
>TypeOnlyExportB : Symbol(TypeOnlyExportB, Decl(verbatimModuleSyntaxEmptyNamedImport_test.ts, 3, 24))

ValueExport as ValueExportB,
>ValueExport : Symbol(DefaultExportA, Decl(verbatimModuleSyntaxEmptyNamedImport_module.d.ts, 0, 0))
>ValueExportB : Symbol(ValueExportB, Decl(verbatimModuleSyntaxEmptyNamedImport_test.ts, 4, 41))

} from "verbatimModuleSyntaxEmptyNamedImport_module";
import DefaultExportC, {
>DefaultExportC : Symbol(DefaultExportC, Decl(verbatimModuleSyntaxEmptyNamedImport_test.ts, 7, 6))

ValueExport as RenamedValueExportC,
>ValueExport : Symbol(DefaultExportA, Decl(verbatimModuleSyntaxEmptyNamedImport_module.d.ts, 0, 0))
>RenamedValueExportC : Symbol(RenamedValueExportC, Decl(verbatimModuleSyntaxEmptyNamedImport_test.ts, 7, 24))

} from "verbatimModuleSyntaxEmptyNamedImport_module";
import DefaultExportD from "verbatimModuleSyntaxEmptyNamedImport_module";
>DefaultExportD : Symbol(DefaultExportD, Decl(verbatimModuleSyntaxEmptyNamedImport_test.ts, 10, 6))

import { type TypeOnlyExport as RenamedTypeOnlyExportE } from "verbatimModuleSyntaxEmptyNamedImport_module";
>TypeOnlyExport : Symbol(DefaultExportA, Decl(verbatimModuleSyntaxEmptyNamedImport_module.d.ts, 0, 0))
>RenamedTypeOnlyExportE : Symbol(RenamedTypeOnlyExportE, Decl(verbatimModuleSyntaxEmptyNamedImport_test.ts, 11, 8))

import { ValueExport as RenamedValueExportF } from "verbatimModuleSyntaxEmptyNamedImport_module";
>ValueExport : Symbol(DefaultExportA, Decl(verbatimModuleSyntaxEmptyNamedImport_module.d.ts, 0, 0))
>RenamedValueExportF : Symbol(RenamedValueExportF, Decl(verbatimModuleSyntaxEmptyNamedImport_test.ts, 12, 8))

import * as NamespaceImportG from "verbatimModuleSyntaxEmptyNamedImport_module";
>NamespaceImportG : Symbol(NamespaceImportG, Decl(verbatimModuleSyntaxEmptyNamedImport_test.ts, 13, 6))

new DefaultExportA();
>DefaultExportA : Symbol(DefaultExportA, Decl(verbatimModuleSyntaxEmptyNamedImport_test.ts, 0, 6))

new DefaultExportB();
>DefaultExportB : Symbol(DefaultExportB, Decl(verbatimModuleSyntaxEmptyNamedImport_test.ts, 3, 6))

new DefaultExportC();
>DefaultExportC : Symbol(DefaultExportC, Decl(verbatimModuleSyntaxEmptyNamedImport_test.ts, 7, 6))

new DefaultExportD();
>DefaultExportD : Symbol(DefaultExportD, Decl(verbatimModuleSyntaxEmptyNamedImport_test.ts, 10, 6))

console.log(ValueExportB);
>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
>console : Symbol(console, Decl(lib.dom.d.ts, --, --))
>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
>ValueExportB : Symbol(ValueExportB, Decl(verbatimModuleSyntaxEmptyNamedImport_test.ts, 4, 41))

console.log(RenamedValueExportC);
>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
>console : Symbol(console, Decl(lib.dom.d.ts, --, --))
>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
>RenamedValueExportC : Symbol(RenamedValueExportC, Decl(verbatimModuleSyntaxEmptyNamedImport_test.ts, 7, 24))

console.log(RenamedValueExportF);
>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
>console : Symbol(console, Decl(lib.dom.d.ts, --, --))
>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
>RenamedValueExportF : Symbol(RenamedValueExportF, Decl(verbatimModuleSyntaxEmptyNamedImport_test.ts, 12, 8))

console.log(NamespaceImportG.ValueExport);
>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
>console : Symbol(console, Decl(lib.dom.d.ts, --, --))
>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
>NamespaceImportG : Symbol(NamespaceImportG, Decl(verbatimModuleSyntaxEmptyNamedImport_test.ts, 13, 6))

150 changes: 150 additions & 0 deletions tests/baselines/reference/verbatimModuleSyntaxEmptyNamedImport.types
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
//// [tests/cases/compiler/verbatimModuleSyntaxEmptyNamedImport.ts] ////

=== verbatimModuleSyntaxEmptyNamedImport_module.ts ===
export const ValueExport = 0;
>ValueExport : 0
> : ^
>0 : 0
> : ^

export type TypeOnlyExport = number;
>TypeOnlyExport : number
> : ^^^^^^

const DefaultExport = class {};
>DefaultExport : typeof DefaultExport
> : ^^^^^^^^^^^^^^^^^^^^
>class {} : typeof DefaultExport
> : ^^^^^^^^^^^^^^^^^^^^

export default DefaultExport;
>DefaultExport : typeof DefaultExport
> : ^^^^^^^^^^^^^^^^^^^^

=== verbatimModuleSyntaxEmptyNamedImport_module.d.ts ===
declare module "verbatimModuleSyntaxEmptyNamedImport_module";
>"verbatimModuleSyntaxEmptyNamedImport_module" : any

=== verbatimModuleSyntaxEmptyNamedImport_test.ts ===
import DefaultExportA, {
>DefaultExportA : any
> : ^^^

type TypeOnlyExport as TypeOnlyExportA,
>TypeOnlyExport : any
> : ^^^
>TypeOnlyExportA : any
> : ^^^

} from "verbatimModuleSyntaxEmptyNamedImport_module";
import DefaultExportB, {
>DefaultExportB : any
> : ^^^

type TypeOnlyExport as TypeOnlyExportB,
>TypeOnlyExport : any
> : ^^^
>TypeOnlyExportB : any
> : ^^^

ValueExport as ValueExportB,
>ValueExport : any
> : ^^^
>ValueExportB : any
> : ^^^

} from "verbatimModuleSyntaxEmptyNamedImport_module";
import DefaultExportC, {
>DefaultExportC : any
> : ^^^

ValueExport as RenamedValueExportC,
>ValueExport : any
> : ^^^
>RenamedValueExportC : any
> : ^^^

} from "verbatimModuleSyntaxEmptyNamedImport_module";
import DefaultExportD from "verbatimModuleSyntaxEmptyNamedImport_module";
>DefaultExportD : any
> : ^^^

import { type TypeOnlyExport as RenamedTypeOnlyExportE } from "verbatimModuleSyntaxEmptyNamedImport_module";
>TypeOnlyExport : any
> : ^^^
>RenamedTypeOnlyExportE : any
> : ^^^

import { ValueExport as RenamedValueExportF } from "verbatimModuleSyntaxEmptyNamedImport_module";
>ValueExport : any
> : ^^^
>RenamedValueExportF : any
> : ^^^

import * as NamespaceImportG from "verbatimModuleSyntaxEmptyNamedImport_module";
>NamespaceImportG : any

new DefaultExportA();
>new DefaultExportA() : any
>DefaultExportA : any

new DefaultExportB();
>new DefaultExportB() : any
>DefaultExportB : any

new DefaultExportC();
>new DefaultExportC() : any
>DefaultExportC : any

new DefaultExportD();
>new DefaultExportD() : any
>DefaultExportD : any

console.log(ValueExportB);
>console.log(ValueExportB) : void
> : ^^^^
>console.log : (...data: any[]) => void
> : ^^^^ ^^ ^^^^^
>console : Console
> : ^^^^^^^
>log : (...data: any[]) => void
> : ^^^^ ^^ ^^^^^
>ValueExportB : any

console.log(RenamedValueExportC);
>console.log(RenamedValueExportC) : void
> : ^^^^
>console.log : (...data: any[]) => void
> : ^^^^ ^^ ^^^^^
>console : Console
> : ^^^^^^^
>log : (...data: any[]) => void
> : ^^^^ ^^ ^^^^^
>RenamedValueExportC : any

console.log(RenamedValueExportF);
>console.log(RenamedValueExportF) : void
> : ^^^^
>console.log : (...data: any[]) => void
> : ^^^^ ^^ ^^^^^
>console : Console
> : ^^^^^^^
>log : (...data: any[]) => void
> : ^^^^ ^^ ^^^^^
>RenamedValueExportF : any

console.log(NamespaceImportG.ValueExport);
>console.log(NamespaceImportG.ValueExport) : void
> : ^^^^
>console.log : (...data: any[]) => void
> : ^^^^ ^^ ^^^^^
>console : Console
> : ^^^^^^^
>log : (...data: any[]) => void
> : ^^^^ ^^ ^^^^^
>NamespaceImportG.ValueExport : any
>NamespaceImportG : any
> : ^^^
>ValueExport : any
> : ^^^

37 changes: 37 additions & 0 deletions tests/cases/compiler/verbatimModuleSyntaxEmptyNamedImport.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// @target: esnext
// @module: preserve
// @verbatimModuleSyntax: true

// @filename: verbatimModuleSyntaxEmptyNamedImport_module.ts
export const ValueExport = 0;
export type TypeOnlyExport = number;
const DefaultExport = class {};
export default DefaultExport;

// @filename: verbatimModuleSyntaxEmptyNamedImport_module.d.ts
declare module "verbatimModuleSyntaxEmptyNamedImport_module";

// @filename: verbatimModuleSyntaxEmptyNamedImport_test.ts
import DefaultExportA, {
type TypeOnlyExport as TypeOnlyExportA,
} from "verbatimModuleSyntaxEmptyNamedImport_module";
import DefaultExportB, {
type TypeOnlyExport as TypeOnlyExportB,
ValueExport as ValueExportB,
} from "verbatimModuleSyntaxEmptyNamedImport_module";
import DefaultExportC, {
ValueExport as RenamedValueExportC,
} from "verbatimModuleSyntaxEmptyNamedImport_module";
import DefaultExportD from "verbatimModuleSyntaxEmptyNamedImport_module";
import { type TypeOnlyExport as RenamedTypeOnlyExportE } from "verbatimModuleSyntaxEmptyNamedImport_module";
import { ValueExport as RenamedValueExportF } from "verbatimModuleSyntaxEmptyNamedImport_module";
import * as NamespaceImportG from "verbatimModuleSyntaxEmptyNamedImport_module";

new DefaultExportA();
new DefaultExportB();
new DefaultExportC();
new DefaultExportD();
console.log(ValueExportB);
console.log(RenamedValueExportC);
console.log(RenamedValueExportF);
console.log(NamespaceImportG.ValueExport);
Loading