Skip to content

Commit 262286c

Browse files
committed
Added a warning if a type node is not exported because it was renamed due to name collisions
Fixes #288
1 parent 07e0a53 commit 262286c

File tree

1 file changed

+28
-7
lines changed

1 file changed

+28
-7
lines changed

src/bundle-generator.ts

+28-7
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ import { generateOutput, ModuleImportsSet, OutputInputData } from './generate-ou
4141
import {
4242
normalLog,
4343
verboseLog,
44+
warnLog,
4445
} from './logger';
4546
import { CollisionsResolver } from './collisions-resolver';
4647

@@ -1101,7 +1102,9 @@ export function generateDtsBundle(entries: readonly EntryPointConfig[], options:
11011102
return collisionsResolver.resolveReferencedIdentifier(nodeName as ts.Identifier) === exportedName;
11021103
}
11031104

1104-
return generateOutput(
1105+
const renamedAndNotExplicitlyExportedTypes: ts.NamedDeclaration[] = [];
1106+
1107+
const output = generateOutput(
11051108
{
11061109
...collectionResult,
11071110
resolveIdentifierName: (identifier: ts.Identifier | ts.QualifiedName | ts.PropertyAccessEntityNameExpression): string | null => {
@@ -1123,7 +1126,7 @@ export function generateDtsBundle(entries: readonly EntryPointConfig[], options:
11231126
// an export keyword (like interface, type, etc) otherwise, if there are
11241127
// only re-exports with renaming (like export { foo as bar }) we don't need
11251128
// to put export keyword for this statement because we'll re-export it in the way
1126-
let result = statementExports.length === 0 || statementExports.find((exp: SourceFileExport) => {
1129+
const isExplicitlyExported = statementExports.find((exp: SourceFileExport) => {
11271130
if (ts.isVariableStatement(statement)) {
11281131
for (const variableDeclaration of statement.declarationList.declarations) {
11291132
if (ts.isIdentifier(variableDeclaration.name)) {
@@ -1148,22 +1151,27 @@ export function generateDtsBundle(entries: readonly EntryPointConfig[], options:
11481151
// e.g. classes/functions/etc must be exported from the root source file to have an "export" keyword
11491152
// by default interfaces/types are exported even if they aren't directly exported (e.g. when they are referenced by other types)
11501153
// but if `exportReferencedTypes` option is disabled we have to check direct export for them either
1151-
const onlyDirectlyExportedShouldBeExported = !exportReferencedTypes
1154+
const onlyExplicitlyExportedShouldBeExported = !exportReferencedTypes
11521155
|| ts.isClassDeclaration(statement)
11531156
|| (ts.isEnumDeclaration(statement) && !hasNodeModifier(statement, ts.SyntaxKind.ConstKeyword))
11541157
|| ts.isFunctionDeclaration(statement)
11551158
|| ts.isVariableStatement(statement)
11561159
|| ts.isModuleDeclaration(statement);
11571160

1158-
if (onlyDirectlyExportedShouldBeExported) {
1161+
if (onlyExplicitlyExportedShouldBeExported) {
11591162
// "valuable" statements must be re-exported from root source file
11601163
// to having export keyword in declaration file
1161-
result = result && statementExports.length !== 0;
1162-
} else if (isNodeNamedDeclaration(statement) && !isExportedWithLocalName(statement, getNodeName(statement)!.getText())) { // eslint-disable-line @typescript-eslint/no-non-null-assertion
1164+
return isExplicitlyExported;
1165+
}
1166+
1167+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
1168+
if (isNodeNamedDeclaration(statement) && !isExportedWithLocalName(statement, getNodeName(statement)!.getText())) {
1169+
// if a type node was renamed because of name collisions it shouldn't be exported with its new name
1170+
renamedAndNotExplicitlyExportedTypes.push(statement);
11631171
return false;
11641172
}
11651173

1166-
return result;
1174+
return isExplicitlyExported || statementExports.length === 0;
11671175
},
11681176
needStripConstFromConstEnum: (constEnum: ts.EnumDeclaration) => {
11691177
if (!program.getCompilerOptions().preserveConstEnums || !outputOptions.respectPreserveConstEnum) {
@@ -1195,5 +1203,18 @@ export function generateDtsBundle(entries: readonly EntryPointConfig[], options:
11951203
noBanner: outputOptions.noBanner,
11961204
}
11971205
);
1206+
1207+
if (renamedAndNotExplicitlyExportedTypes.length !== 0) {
1208+
warnLog(`The following type nodes were renamed because of the name collisions and will not be exported from the generated bundle:\n- ${
1209+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
1210+
renamedAndNotExplicitlyExportedTypes.map(node => `${getNodeName(node)!.getText()} (from ${node.getSourceFile().fileName})`).join('\n- ')
1211+
}${
1212+
'\n'
1213+
}This might lead to unpredictable and unexpected output, and possible breaking changes to your API.${
1214+
'\n'
1215+
}Consider either (re-)exporting them explicitly from the entry point, or disable --export-referenced-types option ('output.exportReferencedTypes' in the config).`);
1216+
}
1217+
1218+
return output;
11981219
});
11991220
}

0 commit comments

Comments
 (0)