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
8 changes: 8 additions & 0 deletions apps/api-extractor/src/generators/ApiReportGenerator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,14 @@ export class ApiReportGenerator {
break;

case ts.SyntaxKind.ExportKeyword:
if (DtsEmitHelpers.isExportKeywordInNamespaceExportDeclaration(span.node)) {
// This is an export declaration inside a namespace - preserve the export keyword
break;
}
// Otherwise, delete the export keyword -- we will re-add it below
span.modification.skipAll();
break;

case ts.SyntaxKind.DefaultKeyword:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does the default need to be retained in these cases as well?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, DefaultKeyword does not need the same treatment because export default cannot appear inside a namespace.

case ts.SyntaxKind.DeclareKeyword:
// Delete any explicit "export" or "declare" keywords -- we will re-add them below
Expand Down
19 changes: 19 additions & 0 deletions apps/api-extractor/src/generators/DtsEmitHelpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import type { Collector } from '../collector/Collector';
import type { Span } from '../analyzer/Span';
import type { IndentedWriter } from './IndentedWriter';
import { SourceFileLocationFormatter } from '../analyzer/SourceFileLocationFormatter';
import { TypeScriptHelpers } from '../analyzer/TypeScriptHelpers';

/**
* Some common code shared between DtsRollupGenerator and ApiReportGenerator.
Expand Down Expand Up @@ -171,4 +172,22 @@ export class DtsEmitHelpers {
}
}
}

/**
* Checks if an export keyword is part of an ExportDeclaration inside a namespace
* (e.g., "export { Foo, Bar };" inside "declare namespace SDK { ... }").
* In that case, the export keyword must be preserved, otherwise the output is invalid TypeScript.
*/
public static isExportKeywordInNamespaceExportDeclaration(node: ts.Node): boolean {
if (node.parent && ts.isExportDeclaration(node.parent)) {
const moduleBlock: ts.ModuleBlock | undefined = TypeScriptHelpers.findFirstParent(
node,
ts.SyntaxKind.ModuleBlock
);
if (moduleBlock) {
return true;
}
}
return false;
}
}
8 changes: 8 additions & 0 deletions apps/api-extractor/src/generators/DtsRollupGenerator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,14 @@ export class DtsRollupGenerator {
break;

case ts.SyntaxKind.ExportKeyword:
if (DtsEmitHelpers.isExportKeywordInNamespaceExportDeclaration(span.node)) {
// This is an export declaration inside a namespace - preserve the export keyword
break;
}
// Otherwise, delete the export keyword -- we will re-add it below
span.modification.skipAll();
break;

case ts.SyntaxKind.DefaultKeyword:
case ts.SyntaxKind.DeclareKeyword:
// Delete any explicit "export" or "declare" keywords -- we will re-add them below
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ export namespace n1 {
// (undocumented)
export class SomeClass2 extends SomeClass1 {
}
{};
export {};
}

// @public (undocumented)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ export declare namespace n1 {
export class SomeClass3 {
}
}
{};
export {};
}

/** @public */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ export namespace SomeNamespace1 {
}
// (undocumented)
export function someFunction3(): ForgottenExport3;
{};
export {};
}

// (No @packageDocumentation comment for this package)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ export declare namespace SomeNamespace1 {
export class ForgottenExport3 {
}
export function someFunction3(): ForgottenExport3;
{};
export {};
}

export { }
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,13 @@ export namespace n1 {
export function someFunction2(): SomeType2;
// (undocumented)
export type SomeType2 = number;
{};
export {};
}
// (undocumented)
export function someFunction1(): SomeType1;
// (undocumented)
export type SomeType1 = number;
{};
export {};
}

// @public (undocumented)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ export declare namespace n1 {
export type SomeType3 = number;
export function someFunction3(): n2.n3.SomeType3;
}
{};
export {};
}
{};
export {};
}

/** @public */
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"changes": [
{
"comment": "Fix missing 'export' keyword for namespace re-exports that produced invalid TypeScript output",
"type": "patch",
"packageName": "@microsoft/api-extractor"
}
],
"packageName": "@microsoft/api-extractor",
"email": "chris@matterport.com"
}