Skip to content

Latest commit

 

History

History
175 lines (111 loc) · 7.17 KB

learning_javascript_jsdoc.md

File metadata and controls

175 lines (111 loc) · 7.17 KB
path title
/learnings/javascript_jsdoc
Learnings: Javascript: JSDoc

Table Of Contents

Q: How can I link to a typedef in another file <<JSDoc_Linking_To_Typedefs_Or_Classes>>

The Good Way

jsdoc/jsdoc#969 (comment)

a.js
  /**
   * @module MyModule
  */

   /**
    * @typedef MyTypdef
    * @property {string} name
    */

b.js
  /**
   * @method foobar
   * @param { module:MyModule~MyTypedef } opt options or initial config values
   */
   function foobar(opt)

~ means "instance" . means static object

and global modules / files not explicitly given a module

Typedefs (and other functions?) that aren't explicitly part of a module are put in the global namespace.

Thus if you access these from other files you don't need special syntax for your rendered jsdocs to link to them.

a work around to force a typedef to be a global even if it's inside a module

If you have properly put everything in a @module you can force a particular declaration to be put in the global namespace anyway. This would allow you to sacrifice a bit of namespace purity for ease of use (because you can just use the name, as if it was part of a global module).

Example

   /**
    * @global
    * @typedef MyTypdef
    * @property {string} name
    */

Really forcing the issue with an identifier

See ESLint_Forcing_Import_Of_Some_Identifier

<<Javascript_Typechecking_With_JSDoc>>

We can use JSDocs + some typescript magic to achieve this.

Good articles on this

Components involved

JSDoc <<Javascript_JsDocs_And_Typescript_For_Typechecking>>

You may - and in fact I really want - to not break jsdoc generation when doing this. There are several problems with this currently (May 2019).

Using built in JSDocs ways of linking object declarations together

Also broken: IntelliSense thinks the module: literal is a filename

Even the global tricks like not namespacing things or making things global?

Nope.

Using Clever Typescript ways to create a type then import the typedef: They don't work (with pure jsdoc)

This:

  1. Breaks running jsdoc, because it doesn't know what to do with the Typescript syntax in the middle of the declaration
  2. Looks kind of weird: you have to essentially stub every declaration from another file that you want to use.

See a good explanation of the "import type" trick and where it breaks down:

Github Issues / PRs around this:

A plugin to the rescue: jsdoc-plugin-typescript

jsdoc-plugin-typescript lets us put typescript in our JSDoc, so we can do the Clever Typescript thing.

/**
* @typedef { import('./a').Team} Team
*/

/**
* Display the team
*
* @param {Team} team the team to display for
*/
function displayTeam(team) { ... }

It has only two (relatively minor problems):

  1. when it expands the typescript the type, in the rendered JS, is not hyperlinked anymore (but the type appears inline in the module page, not requiring people to go find it, so that's a win).
  2. Requires(?) jsdoc 3.6
  3. requires typedef stubs. (Placing the typescript inline in the @param declaration doesn't seem to work)

But it has some major ADVANTAGES:

  1. eslint, even with eslint-plugin-jsdoc seems to be relatively happy with the typescript in the stub declaration
  2. Typechecking / IntelliSense totally works!

See it is in use / I made a sample repo

ESLINT

You're likely running eslint in your project, so you have to make sure that any code you write stays valid. Because you're not really writing Typescript, you can't go down that route entirely

ESLINT + JSDoc checking

You are running eslint-plugin-jsdoc, right?

Micosoft Typescript / Javascript Language server

Use a more recent version of TypeScript?

https://stackoverflow.com/a/50255744/224334

Can use the command prompt in VCS to select Typescript version: make sure this is > 2.9???

... which my work if both the source and caller location are in the same jsDoc module...

Issues / PR that avoids the JSDoc import mess by doing it natively in TS

Because if TS had native support you would be able to do TS-like typechecking, even / especially if you could set your declarations (or whatever) to global.

See also