rushstack icon indicating copy to clipboard operation
rushstack copied to clipboard

[api-extractor] TSDoc @inheritDoc blocks are not copied.

Open jsamr opened this issue 5 years ago • 4 comments

Please prefix the issue title with the project name i.e. [rush], [api-extractor] etc.

Is this a feature or a bug?

  • [ ] Feature
  • [X] Bug

I believe it is a bug, but it could be that I misunderstood the responsibility of api-extractor tool. I have based those assumptions on the @inheritDoc documentation here which states:

The @inheritDoc tag automatically copies documentation content from another declaration. This avoids duplication when two declarations have the same behavior, and thus should have identical documentation.

If the issue is a bug, how can we reproduce it? Please provide detailed steps and include a GitHub branch if applicable. Your issue will get resolved faster if you can make it easy to investigate.

given this declaration file,

// lib/index.d.ts

/**
 * @public
 */
export declare interface A {
  /**
   * This is a description of foo, which usually bars.
   */
  foo: string;
}

/**
 * @public
 */
export declare interface B {
  /** {@inheritDoc A.foo} */
  foo: string;
}

and running

npx api-extractor run --local --verbose

the resulting rollup is

// dist/api-extractor-bug.d.ts

/**
 * @public
 */
export declare interface A {
  /**
   * This is a description of foo, which usually bars.
   */
  foo: string;
}

/**
 * @public
 */
export declare interface B {
  /** {@inheritDoc A.foo} */
  foo: string;
}

export { }

Instead, I would have expected

diff --git a/dist/api-extractor-bug.d.ts b/dist/api-extractor-bug.d.ts
index 82f23f4..f98ca41 100644
--- a/dist/api-extractor-bug.d.ts
+++ b/dist/api-extractor-bug.d.ts
@@ -13,7 +13,9 @@ export declare interface A {
  * @public
  */
 export declare interface B {
-  /** {@inheritDoc A.foo} */
+  /**
+   * This is a description of foo, which usually bars.
+   */
   foo: string;
 }

see https://github.com/jsamr/api-extractor-inheritdoc for a full reproduction

If this is a bug, please provide the tool version, Node.js version, and OS.

  • Tool: API Extractor
  • Tool Version: 7.9.2
  • Node Version: 14.5.0
    • Is this a LTS version? No
    • Have you tested on a LTS version? No
  • OS: Manjaro Linux

jsamr avatar Jul 31 '20 13:07 jsamr

@k8w and @tylerbutler encountered this same issue in #2671

octogonz avatar Sep 11 '21 00:09 octogonz

🤔 @inheritDoc was originally introduced to support API Documenter, which predates the .d.ts rollup feature. In theory, if your tooling supports TSDoc, it shouldn't matter whether @inheritDoc is expanded in the .d.ts code comments or not. Expanding could even have a downside of making the .d.ts file harder to read, which is not a concern for an API website (because it has navigation and pagination to manage that problem).

On the other hand, one advantage of expanding @inheritDoc is that you can include docs from unreachable API items, for example a TypeScript interface that is used internally and not shipped.

I think I agree that API Extractor should implement this feature, at least as a configuration option. 👍

Implementing this seems to get us involved with transformation of /** */ comments, since @inheritDoc is only supposed to copy a subset of the content. Today API Extractor does not reformat doc comments -- it essentially just copies them verbatim to the .d.ts file and fixes up the indentation.

The tsdoc/src/emitters/TSDocEmitter.ts API is supposed to provide a full featured engine for reformatting TSDoc comments in a normalized form, which I think is the tool we'd want for this. However it's not quite finished -- it's missing word-wrapping for example. (Which was actually a feature for the .api.json serializer, which prefers a compact representation.)

Anyway without thinking about this deeper, that's the approach I would start with. Maybe there is a shortcut? Suggestions welcome.

octogonz avatar Sep 11 '21 00:09 octogonz

@octogonz Thanks for your answer! Another important advantage is for IDE integration. Currently in VSCode, we just see the tag which kind of defies the purpose.

jsamr avatar Sep 11 '21 10:09 jsamr

I don't get it. I just tried it and nothing happens.

Why is it even documented on a page, if it doesn't work?

iJungleboy avatar Jun 24 '22 16:06 iJungleboy