11

Assuming I have a typedef type in a js module

// somewhere/foo.js
/**
 * @module
 */ 
/**
 * @typedef Foo
 * @type {object}
 * property {string} bar - some property
 */

Is it possible to reference this type in another module, so that in the HTML page generated by jsdoc, the type is displayed as a link to the typedef-ed module ?

I tried variations of this, but nothing seems to work...

// somewhere_else/bar.js
/**
 * @module
 */
/**
 * @param {somewhere/foo/Foo} foo - some param
 */
export default function doStuff(foo) {
  ...
}
phtrivier
  • 12,156
  • 4
  • 42
  • 73

5 Answers5

9

This works for me ...

// somewhere/foo.js
/**
 * @module foo
 */
/**
 * @typedef module:foo.Foo
 * @type {object}
 * @property {string} bar - some property
 */

and ...

// somewhere_else/bar.js
/// <reference path="foo.js" />
/**
 * @module bar
 */
/**
 * @param {module:foo.Foo} foo - some param
 */
function doStuff(foo) {
  //...
};
Slava Ivanov
  • 5,860
  • 2
  • 19
  • 31
  • Fully qualifying the module in the @typedef does work (I personnaly wrote `@typedef {Object} module:foo/Foo` , but that's a matter of taste.) However : 1/ the `/// ` does not seem required, and I could not find it documented anywhere. 2/ if the module has a long path (like 'somewhere/foo') typing it everywhere is a bit tedious, do you know of any trick to alias it somehow ? – phtrivier Mar 17 '17 at 09:57
  • @phtrivier 1. sorry, reference is just a copy and paste from my test, ignore it. 2. Totally agree with you, a bit tedious; unfortunately "alias" is the way we document (specially with prototypes). In fact it's not that bad, as it looks. I see the benefit of it: developer who uses this method or type would exactly know where is it defined, so it helps not just to create correct documentation, but during development to look for references efficient. Yet another way it to use "@exports", but I didn't discover this option, so cannot comment. – Slava Ivanov Mar 17 '17 at 13:44
7

The above answer shows up high in search results so I'm documenting what worked for me in case it helps someone in a similar situation.

I'm using Visual Studio code for a node project with // @ts-check on all my modules. Using the above syntax hiccups on the module: syntax. Also, the code assistance doesn't work properly. It took me a while but the answer ended up being quite simple

If I have the typedef myTypedef in a module myModule then in the second module where I require myModule
mm = require(myModule)
I can use something like
/** @param {mm.myTypedef} myParamName */

Tod
  • 7,806
  • 5
  • 46
  • 85
0

I've tried both of the above approaches.

Firstly, in the case of @typedef module:foo.Foo, VSCode treated the usage of Foo within the same file as any. Which I didn't find acceptable.

Secondly, when using ES6 imports the following issue emerges:

import foo from 'foo'

/** @param {foo.Foo} a - Error Foo does not exist on foo */ 

On the other hand VSCode recognizes import { Foo } from 'foo' without even using the JSDoc module syntax:

/**
 * @module bar
 */

What's more I was also able to reference a property on the imported type, namely:

import { Foo } from 'foo'

/** @param {Foo['bar']} bar */

Note

This project uses Babel and assume compiling code which uses type imports in not feasible without a transpiler.

Mateja Petrovic
  • 2,125
  • 1
  • 15
  • 31
0

Many libraries export types from their root file, to access those in typedefs, change your import to use the import * as format.

For example:

import * as testingLibrary from '@testing-library/react';


/** 
 * @returns {testingLibrary.RenderResult}
 */
export function myCustomRender() { }

Zach Posten
  • 2,420
  • 2
  • 25
  • 36
0

I'm working with vscode-powertools script which provides access to vscode module at runtime (as opposed to it being available to VSCode at edit time via the local node_modules).

If I would try to import the types with the usual jsdoc import

//@ts-check
/** @typedef {import('c:/Users/USERNAME/.vscode/extensions/ego-digital.vscode-powertools-0.64.0/node_modules/vscode').TextEditor} TextEditor */

I would be getting the File is not a module error:

File 'C:/Users/USERNAME/.vscode/extensions/ego-digital.vscode-powertools-0.64.0/node_modules/vscode/vscode.d.ts' is not a module. ts(2306)

So here's the trick I'm using to typecheck that kind of script:

//@ts-check
/// <reference types="c:/Users/USERNAME/.vscode/extensions/ego-digital.vscode-powertools-0.64.0/node_modules/vscode" /> 

// Allows us to reference the `vscode` module with jsdoc `@type`
async function vscodeⁱ() {if (1 == 1) return null; return import ('vscode')}

exports.execute = async (args) => {
  // Allows us to reference the `vscode` module with jsdoc `@type`
  const vscode = await vscodeⁱ()

  /** @type {vscode} */
  const vs = args.require ('vscode')

  // NB: The following code is fully typed in VSCode
  const windowᵛ = vs.window
  const editorᵛ = windowᵛ.activeTextEditor
  const start = editorᵛ.selection.start
}
ArtemGr
  • 9,567
  • 2
  • 44
  • 75