Can I define all custom types in a separate file (e.g. types.jsdoc
), so that they can be reused throughout the application? What's the right way to do it?
/**
* 2d coordinates.
* @typedef {Object} Coordinates
* @property {Number} x - Coordinate x.
* @property {Number} y - Coordinate y.
*/
You can define types in a module (eg. typedefs.js
). The module contains your JSDoc typdefs and can simply export an unused property.
// typedefs.js
/**
* @typdef foo
* @property {string} bar
*/
// etc.
exports.unused = {};
To use it, import the module where you need to reference these typdefs:
const typedefs = require("./typedefs");
/** @type {typedefs.foo} */
const fb = { bar: "hello" };
You may wish to annotate typedefs.js
as a @module
or @namespace
. Because I'm using "tsd-jsdoc" to generate a types.d.ts
file, and due to the way TypeScript now interprets modules vs. namespaces, I've annotated my typedefs.js
file as a @namespace
and documented each typedef as a member of that namespace:
/**
* @namespace typedefs
*/
/**
* @typedef foo
* @property {string} bar
* @memberof typdefs
*/
Hope that helps.
This is a TypeScript-flavored JSDoc specific answer, but I'm having success using a triple-slash directive to "import" all the types from another file. This has the advantage of not actually adding an unused import
which can upset linters and bundlers.
I'm putting my shared types in one file called typedefs.js
like this:
// typedefs.js
/**
* @typedef {Object} Foo
* @property {string} bar
*/
/**
* @typedef {Object} Baz
* @property {number} buzz
*/
and then using /// <reference path="typedefs.js" />
in the other files to access the shared types like this:
// randomThing.js
/// <reference path="typedefs.js" />
/**
* Turn a Foo into a Baz
*
* @param {Foo} a
* @return {Baz}
export function (a) {
return { buzz: a.bar.length };
}
The tricky thing though is that now typedefs.js
is just being referenced in a comment, bundlers like rollup miss it completely. So I'm combining it with my old consts.js
that exports a few constants and is imported in at least one place. That way the typedefs are still included in the rollup output.
I hope someone else finds this helpful.
p.s. rollup will completely exclude a pure JSDoc typedefs.js
file _even if you have import './typedefs.js'
because of tree-shaking! Gotta run rollup with --no-treeshake
to keep those comments in the rollup output.
In vscode, the import('./path/to/types.js').def
tag works perfectly fine.
For e.g.types.js
/**
* @typedef {Object} connection
* @property {String} id
* @property {Number} pingRetries
* @property {(data:Object) => void} sendJSON
*/
exports.unused = {};
And someFile.js
/**
* @param {import('./types').connection} param
*/
const someFunc = (param) => {}
Also, note that the exports.unused = {}
is necessary in the types.js
file, otherwise the auto-import of import('./types')
would not work and you may have to type it by yourself.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With