@@ -541,7 +541,7 @@ namespace ts {
541
541
}
542
542
543
543
function declareModuleMember ( node : Declaration , symbolFlags : SymbolFlags , symbolExcludes : SymbolFlags ) : Symbol {
544
- const hasExportModifier = getCombinedModifierFlags ( node ) & ModifierFlags . Export ;
544
+ const hasExportModifier = ! ! ( getCombinedModifierFlags ( node ) & ModifierFlags . Export ) || jsdocTreatAsExported ( node ) ;
545
545
if ( symbolFlags & SymbolFlags . Alias ) {
546
546
if ( node . kind === SyntaxKind . ExportSpecifier || ( node . kind === SyntaxKind . ImportEqualsDeclaration && hasExportModifier ) ) {
547
547
return declareSymbol ( container . symbol . exports ! , container . symbol , node , symbolFlags , symbolExcludes ) ;
@@ -567,7 +567,7 @@ namespace ts {
567
567
// and this case is specially handled. Module augmentations should only be merged with original module definition
568
568
// and should never be merged directly with other augmentation, and the latter case would be possible if automatic merge is allowed.
569
569
if ( isJSDocTypeAlias ( node ) ) Debug . assert ( isInJSFile ( node ) ) ; // We shouldn't add symbols for JSDoc nodes if not in a JS file.
570
- if ( ( ! isAmbientModule ( node ) && ( hasExportModifier || container . flags & NodeFlags . ExportContext ) ) || isJSDocTypeAlias ( node ) ) {
570
+ if ( ! isAmbientModule ( node ) && ( hasExportModifier || container . flags & NodeFlags . ExportContext ) ) {
571
571
if ( ! container . locals || ( hasSyntacticModifier ( node , ModifierFlags . Default ) && ! getDeclarationName ( node ) ) ) {
572
572
return declareSymbol ( container . symbol . exports ! , container . symbol , node , symbolFlags , symbolExcludes ) ; // No local symbol for an unnamed default!
573
573
}
@@ -583,6 +583,21 @@ namespace ts {
583
583
}
584
584
}
585
585
586
+ function jsdocTreatAsExported ( node : Node ) {
587
+ if ( ! isJSDocTypeAlias ( node ) ) return false ;
588
+ // jsdoc typedef handling is a bit of a doozy, but to summarize, treat the typedef as exported if:
589
+ // 1. It has an explicit name (since by default typedefs are always directly exported, either at the top level or in a container), or
590
+ if ( ! isJSDocEnumTag ( node ) && ! ! node . fullName ) return true ;
591
+ // 2. The thing a nameless typedef pulls its name from is implicitly a direct export (either by assignment or actual export flag).
592
+ const declName = getNameOfDeclaration ( node ) ;
593
+ if ( ! declName ) return false ;
594
+ if ( isPropertyAccessEntityNameExpression ( declName . parent ) && isTopLevelNamespaceAssignment ( declName . parent ) ) return true ;
595
+ if ( isDeclaration ( declName . parent ) && getCombinedModifierFlags ( declName . parent ) & ModifierFlags . Export ) return true ;
596
+ // This could potentially be simplified by having `delayedBindJSDocTypedefTag` pass in an override for `hasExportModifier`, since it should
597
+ // already have calculated and branched on most of this.
598
+ return false ;
599
+ }
600
+
586
601
// All container nodes are kept on a linked list in declaration order. This list is used by
587
602
// the getLocalNameOfContainer function in the type checker to validate that the local name
588
603
// used for a container is unique.
0 commit comments