in src/assembler.ts [2537:2578]
function _isPrivate(symbol: ts.Symbol): boolean {
// Private identifiers are always private...
if (symbol.name.startsWith('#')) {
return true;
}
const TYPE_DECLARATION_KINDS = new Set([
ts.SyntaxKind.ClassDeclaration,
ts.SyntaxKind.InterfaceDeclaration,
ts.SyntaxKind.EnumDeclaration,
]);
// if the symbol doesn't have a value declaration, we are assuming it's a type (enum/interface/class)
// and check that it has an "export" modifier
if (
!isInternalSymbol(symbol) &&
(!symbol.valueDeclaration || TYPE_DECLARATION_KINDS.has(symbol.valueDeclaration.kind))
) {
let hasExport = false;
for (const decl of symbol.declarations ?? []) {
if (ts.getCombinedModifierFlags(decl) & ts.ModifierFlags.Export) {
hasExport = true;
break;
}
// Handle nested classes from project references
if (ts.isModuleBlock(decl.parent)) {
const moduleDeclaration = decl.parent.parent;
const modifiers = ts.getCombinedModifierFlags(moduleDeclaration);
// The trick is the module is declared as ambient & exported
if ((modifiers & ts.ModifierFlags.Ambient) !== 0 && (modifiers & ts.ModifierFlags.Export) !== 0) {
hasExport = true;
break;
}
}
}
return !hasExport;
}
const decl = symbol.valueDeclaration ?? symbol.declarations?.[0];
return decl != null && (ts.getCombinedModifierFlags(decl) & ts.ModifierFlags.Private) !== 0;
}