Skip to content

RFC: Detecting whether a dependency implements TSDoc #7

Open
@octogonz

Description

@octogonz

Consider this example from API Extractor:

/** @beta */
export interface IPrepareOptions {
  target: string;
}

/** @public */
export interface IWidget {
  /** Renders the widget */
  render(): void;
}

/** @public */
export class Widget implements IWidget {
  /** {@inheritdoc IWidget.render} */  // <-- inherited doc comment
  render(): void;

  prepare(options: IPrepareOptions): void;  // <-- inconsistent visibility error
}

This illustrates a couple kinds of cross references:

  1. Documentation inheritance: The Widget.render docs are copied from IWidget.render using the {@inheritdoc} tag. This avoids having to write duplicate documentation.
  2. Visibility checking: API Extractor allows API items to be marked with a "release tag" such as @beta. For a public release, only the @public definitions will be included in the generated *.d.ts rollup file; the other definitions are trimmed out. In the above example, the analyzer must report an error because if IPrepareOptions gets trimmed, then Widget.prepare won't be able to consumer that interface.

Now, suppose that IWidget and IPrepareOptions are imported from a separate NPM package called widget-lib. This is no problem -- API Extractor can simply parse the TSDoc comments from this file:

./node_modules/widget-lib/lib/index.d.ts

This seems fine on the surface, but the node_modules folder is full of *.d.ts files that have no awareness of API Extractor. Their doc comments might randomly contain a string such as @beta, or they might simply have malformed comments that would normally be reported as a TSDoc error.

We need a way to determine whether a given NPM package actually implements TSDoc or not.

Our proposal is to add a custom field tsdoc to the package.json file format like this:

{
  "name": "widget-lib",
  "version": "1.0.0",
  "main": "lib/index.d.ts",
  "typings": "lib/index.js",
  "tsdoc": {
    "tsdocFlavor": "AEDoc"
  }
}

(Note that the CommonJS spec specifically allows for custom fields.)

Initially, the tsdoc block would support a single field tsdocFlavor that helps tooling to recognize custom extensions to the core TSDoc tags. In the future it might include other fields such as a version number. See this file for a real world prototype of this convention.

Does this seem like a good design?

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions