diff --git a/scripts/generate-api-docs.ts b/scripts/generate-api-docs.ts index ec78d8e..67a127a 100644 --- a/scripts/generate-api-docs.ts +++ b/scripts/generate-api-docs.ts @@ -127,25 +127,22 @@ const generateDocs = (entryFiles: string[], apiConfigFile: string, dry = false) const declaration = exportSymbol.valueDeclaration || exportSymbol.declarations?.[0]; if (!declaration) return; - // If it's a reexport, follow it recursively + // If it's a reexport, resolve it to the underlying symbol (following chains of aliases, + // e.g. a re-export of a re-export) rather than recursing into the whole module it lives in + // -- `getExportsOfModule` above already gives us one entry per exported symbol, so a module + // recursion here would revisit (and duplicate) every other export of that module too. if (exportSymbol.flags & ts.SymbolFlags.Alias) { - const aliasedSymbol = typeChecker.getAliasedSymbol(exportSymbol); + let aliasedSymbol = typeChecker.getAliasedSymbol(exportSymbol); + while (aliasedSymbol.flags & ts.SymbolFlags.Alias) { + aliasedSymbol = typeChecker.getAliasedSymbol(aliasedSymbol); + } const aliasedDeclaration = aliasedSymbol.valueDeclaration || aliasedSymbol.declarations?.[0]; if (aliasedDeclaration) { - const sourceFile = aliasedDeclaration.getSourceFile(); - const moduleSymbol = typeChecker.getSymbolAtLocation(sourceFile); - // If the aliased declaration lives in a module we've already visited (e.g. a - // same-file `export type { Foo }` re-export of a local declaration), recursing - // won't reach it, so add the alias symbol directly. Otherwise follow the reexport. - if (moduleSymbol && !visited.has(moduleSymbol)) { - symbols.push(...getAllExportedSymbols(moduleSymbol, visited)); - } else { - // Push the aliased symbol (not the alias) so downstream sees the real - // declaration and its JSDoc rather than the empty ExportSpecifier. - const hasPublicTag = ts.getJSDocTags(aliasedDeclaration).some(tag => tag.tagName.text === 'public'); - if (hasPublicTag) { - symbols.push(aliasedSymbol); - } + // Push the aliased symbol (not the alias) so downstream sees the real + // declaration and its JSDoc rather than the empty ExportSpecifier. + const hasPublicTag = ts.getJSDocTags(aliasedDeclaration).some(tag => tag.tagName.text === 'public'); + if (hasPublicTag) { + symbols.push(aliasedSymbol); } } }