tsdoc
tsdoc copied to clipboard
RFC: Syntax for @example tag
RFC: Core set of tags for TSDoc brought up the question of the @example tag that could be used to identify examples. I'm forking it into a separate issue since @c69 pointed out that the design is unclear.
Can anyone find samples of its usage in existing documentation systems?
Since TSDoc will support Markdown, how would it interact with that? Maybe something like this?
/**
* Adds two numbers together.
* @example
* Here's a simple example:
* ```
* // Prints "2":
* console.log(add(1,1));
* ```
* @example
* Here's an example with negative numbers:
* ```
* // Prints "0":
* console.log(add(1,-1));
* ```
*/
export function add(x: number, y: number): number {
}
How would an API reference web site leverage these directives?
@aciccarello
In the case of DocFX, we definitely want to move away from inlined samples and into includes (see: file inclusion). As such, I like the proposal of having the tag be Markdown-ready.
I always thought @example is always followed by a sample code, or at least a link to an example file.
If there will be some kind of {@include} (see #22), I would suggest using that in conjunction with markdown, as in the first comment:
/**
* Adds two numbers together.
* @example
* Here's a simple example:
* {@include example1.ts}
* @example
* Here's an example with negative numbers:
* {@include example2.ts}
*/
export function add(x: number, y: number): number {
}
This way, it's easy to include several code snippets within the same example and reuse example codes at several places.
@pgonzal I'm not sure I understand your question but the code you have looks good to me. My main question is where should the example tag block end? Would it be on an empty line or the next block annotation?
@aciccarello I guess your question will be answered here: https://github.com/Microsoft/tsdoc/issues/12
@example could be spec'ed in such a way that it can be used for tests.
/* @example
/* > plusOne(3)
/* 4
One could create a tool that executes plusOne(3) and fails if the result is not 4.
I haven't given much thought to the different scenarios and why this might or might not make sense in the context of JS/TS. Maybe we need a new tag.
/* @example addOne(3)
/* @expect 4
Sorry for the brainstorming.
@kiliancs That seems to me like something that should stay in the example code and not be handled by the documentation tool. Interesting idea though.
/**
* @example
* Adding one adds one
* ```typescript
* import plusOne from 'plus-one';
* import expect from 'test-lib';
*
* const actual = plusOne(3);
* expect(actual).toEqual(4);
* ```
*/
export function plusOne(input: number) {
return input + 1;
}
@pgonzal I can have for Angular documentation tool https://github.com/compodoc/compodoc this kind of @example usage which use TypeScript decorator.
* @example
* Usage example
* ```typescript
* @Component({selector: 'something'}) export class AppComponent {};
* ```
Recently I've been starting to question the need for a dedicated @example tag. It seems like ## Example (a Markdown header) may be able to do the job just as well without defining a new tag.
I suppose depends on your documentation template. Right now API Extractor renders @example blocks basically as headers like you suggest, with a bit of extra logic to autonumber the examples if there are more than one of them. But you could imagine a more elaborate system that indexes the examples, or shows special icons next to example sections, etc.
@dend Does DocFX treat example sections differently from other sections?
Right now API Extractor renders @example blocks
@pgonzal did this work or release in last npm version deployed ?
I just made a test with your playground this morning with my-use case and cannot see informations in the AST generated.
The TSDoc Playground does not implement @example because it is currently specified as "extended" standardization level.
API Extractor is a separate project that incorporates TSDoc, but is not itself part of the TSDoc standard. API Extractor supports the @example tag in version 7.0.0 which is still released under a "beta" NPM disttag; i.e. you have to do npm install @microsoft/api-extractor@beta if you want to try that version.
BTW if @example is popular, I'm fine with updating the playground to demo this feature. However e.g. @sharwell was questioning that above.
I prefer the markdown tactic as an example might not necessarily be all TypeScript.
On another note, think it would be helpful to support a name/title for examples. Maybe in @example Name - ... format, or take the text on the same line as the tag to be the name. This would help in documentation generation - for example, one could have a documentation page with examples hidden under an accordion, and use the title text as the name of each accordion item.
Example (where text on the same line is the name of the example, and code besides TypeScript is included):
/**
* Parses a JSON file.
* @param path - Full path to the file.
* @returns An object containing the JSON data.
* @example Parsing a basic JSON file
* ##Contents of `file.json`:
* ```json
* {
* exampleItem: "text"
* }
* ```
*
* ##Usage:
* ```ts
* const result = parseFile("file.json");
* ```
*
* ##Result:
* ```ts
* {
* exampleItem: 'text',
* }
* ```
*/
That's a good suggestion. Currently API Documenter simply generates names like Example 1, Example 2, etc. Not as informative as it could be.
Maybe in
@example Name - ...format, or take the text on the same line as the tag to be the name.
There's already some precedent, where the @throws tag has a convention that the exception name can be specified using text on the same line as the tag.
/**
* Retrieves metadata about a book from the catalog.
*
* @param isbnCode - the ISBN number for the book
* @returns the retrieved book object
*
* @throws {@link IsbnSyntaxError}
* This exception is thrown if the input is not a valid ISBN number.
*
* @throws {@link book-lib#BookNotFoundError}
* Thrown if the ISBN number is valid, but no such book exists in the catalog.
*
* @public
*/
function fetchBookByIsbn(isbnCode: string): Book;
So maybe a similar convention could be used for @example as in your sample. (BTW markdown headers should probably start with #, to avoid making assumptions about the documenter's heading structure.)
So it could be like this:
/**
* Parses a JSON file.
*
* @param path - Full path to the file.
* @returns An object containing the JSON data.
*
* @example Parsing a basic JSON file
*
* # Contents of `file.json`
* ```json
* {
* "exampleItem": "text"
* }
* ```
*
* # Usage
* ```ts
* const result = parseFile("file.json");
* ```
*
* # Result
* ```ts
* {
* exampleItem: 'text',
* }
* ```
*/
...and might get rendered like this:
Example: Parsing a basic JSON file
Contents of
file.json{ "exampleItem": "text" }Usage
const result = parseFile("file.json");Result
{ exampleItem: 'text', }
The docs mention that inline text should be parsed as headings, but both the api and the playground treat them as normal paragraphs. Is this intentional or just un-implemented?
Adding example title's also breaks whitespace rendering in VSCode which is a pretty big problem.
I've been able to roll my own type extractor to compensate for the lack of support here (although I would have preferred to be able to just use tsdoc / api-extractor), but alas, I can't roll my own VSCode (nor can https://github.com/TypeStrong/typedoc/issues/2440) 😅
Does VSCode use tsdoc for the tooltips? Or should I open an issue on that repo too? If there's anything I can to do help inspire some movement here, please let me know!
Does VSCode use
tsdocfor the tooltips? Or should I open an issue on that repo too? If there's anything I can to do help inspire some movement here, please let me know!
No, how I understand it, VS Code implements a proprietary analysis that isn't based on any spec. It's just a best attempt to render the kinds of /** */ comments most commonly encountered in real world code bases.
We could try to improve that. However because TSDoc's goal is to provide a rigorous and unambiguous syntax, a better approach would be to create a VS Code extension specifically for TSDoc. Then we could perfectly parse TSDoc syntax and provide much better rendering.
If someone's interested in contributing to a project like that, let us know. 🙏 In the past this idea was blocked because we were missing the CI infrastructure for publishing extensions to the VS Code marketplace, but Microsoft solved that recently for us as part of setting up the VS Code extension for Rush (another Rush Stack project).