JSDoc - How to assign a function as a property of another function - jsdoc

Given the following, when I run jsdoc, the output does not show anything for the foo.bar property.
/**
* Foo
*/
const foo = function foo() {
//...
}
/**
* Bar
*/
foo.bar = function bar() {
//...
}
How can I display bar as being a property on foo?

There are a lot of possibilities to achieve this. The following are just a couple of them ...
Use #memberof which is the tag identifies a member symbol that belongs to a parent symbol.
/**
* Foo
*/
const foo = function foo() {
//...
}
/**
* Bar
* #memberof Foo
*/
foo.bar = function bar() {
//...
}
Use #prop which is the tag to easily document a list of static properties of a class, namespace or other object.
/**
* Foo
* #namespace
* #property {object} bar - is this "bar" property?
*/
const foo = function foo() {
//...
}
/**
* Bar
*/
foo.bar = function bar() {
//...
}
You may use #alias as well, it's all depend on what is your Foo and Bar; Are they objects, namespace, functions, properties, etc. I would suggest to read a bit on JSDoc documentation to get to know all the possibilities.

here is a #typedef solution, with property comments
// types.js
/**
* #typedef {(s: string) => number} _SomeFunction
* convert string to number
*
* #typedef {Object} SomeProps
* #property {number} someProp1 some property 1
* #property {string} someProp2 some property 2
* #property {(s: string) => number} someProp3
* some property 3
*
* #typedef {_SomeFunction & SomeProps} SomeFunction
*/
/** #typedef {import("./types.js").SomeFunction} SomeFunction */
/** #type {SomeFunction} */
var f = s => s.length
f.someProp1 = 1
f.someProp2 = ""
f.someProp3 = s => (2 * s.length)

Related

`Rest parameters JSDOC` is not correctly flagged in vscode

Is there something wrong with my code that caused vscode to have no correct tip?
/**
*
* #param {...Object} elementList
* #param {string} elementList[].type
*/
function add(...elementList) {
// vscode tip: elementList is (parameter) elementList: any[]
// expect: elementList is {type: string;}[]
elementList.map(e => e)
}
// use
add({ type: 'div' }, { type: 'h1' })
You want the format #param {type} parameterName, e.g.
/**
* #param {{type: string}[]} elementList
*/
function add(...elementList) {
elementList.map(e => e)
// ^^^^^^^^^^^ (parameter) elementList: {type: string}[]
}
Alternatively, you can create re-usable type definitions with JSDoc:
// Define an Object type named MyElement with one property (type) of type string.
/**
* #typedef {Object} MyElement
* #property {string} type
*/
/**
* #param {MyElement[]} elementList
*/
function add(...elementList) {
elementList.map(e => e)
// ^^^^^^^^^^^ (parameter) elementList: MyElement[]
}

jsdoc typedef global to local, why not overridden?

Props with global type declaration
I want to overwrite it with the local type.
Below is the code and comments.
/* global */
/**
* #typedef {{key: string, value: string}} Props
*/
/**
* #type {Props}
*/
let globalTypeObj = {};
/* local */
class LocalType {
/**
* #typedef {{name: string, age: number}} Props
* #param {Props} props
*/
constructor(props) {} // <- Why doesn't LocalType Props apply here?
}
/**
* #namespace {LocalType} // I used namespace LocalType.
* #type {Props}
*/
let LocalTypeObj = {}; // <- Why doesn't LocalType Props apply here?
Please teach me.

How to comment a method returning a copy of this, using JSDoc?

How to describe, using the JSDoc tags, this derivate() return value? I'm looking for a syntax to describe (#returns) the object creation, resulting from mixin of the current object AND the provided properties, to improve the autocompletion.
I thought to something like #returns #mixes (this, properties) but it isn't a valid syntax, apparently.
const obj = {
/**
* #param {{
* ...properties: *
* }} [properties]
* #returns {{}}
*/
derivate ({ ...properties } = {}) {
return { ...this, ...properties }
}
}
Just found a solution (but tsc doesn't like it, then still open for a better soltion):
/**
* #typedef Obj
* #type {Object}
*/
/**
* #typedef Properties
* #type {Object}
*/
/**
* #typedef Return
* #type {Object}
* #augments Obj
* #augments Properties
*/
/**
* #type {Obj} obj
*/
const obj = {
/**
* #param {Properties} [properties]
* #returns {Return}
*/
derivate ({ ...properties } = {}) {
return { ...this, ...properties }
}
}

How to use Jsdoc to describe an extended class's property that is defined in super class

What I want to do is this:
class A {
someMethod() {
//
}
}
class B {
constructor (options) {
this.dependency = options.dependency;
}
}
class C extends B {
test() {
this.dependency.a. // want a to refer to instance of A class and provide intellisense using jsdocs
}
}
I have tried some stuff on normal objects and it works but I can't get it working on the class or override some property.
here is what I have tried:
/**
* #typedef {Object} WithSomeProp
* #property {{ a: A }} prop
*
* #typedef {C & WithSomeProp} extended
*/
/**
* #type {extended}
*/
let a = {};
a.prop.a.someMethod // works (shows suggestion)
a.test // works
/**
* #typedef {Object} WithOtherProp
* #property {{ a: A }} dependency
*
* #typedef {C & WithOtherProp} extendedTwo
*/
/**
* #type {extendedTwo}
*/
let b = {};
b.dependency. // doesn't work
b.test // works
So overall there isn't any way to override the property definition somehow later on the extended classes to get intellisense support ?
I just realized I can do this instead (I feel dumb now)
class C extends B {
constructor(options) {
super(options);
/**
* #type {A}
*/
this.a = options.dependency.a;
}
test() {
this.a.someMethod // works fine now
}
}

JSDoc reference function in object literal (CommonJS module.exports)

I'm writing a CommonJS module and have all of my methods defined as function definitions within the module. Those methods are then defined in the module.exports object. This is all written with es6 as well.
However, with my annotations, the generated documentation only links to the object definition and does not display the actual documentation for the methods.
// file named utils.js
const regular = require('regular');
const isEmpty = require('lodash.isempty);
/**
* #memberof utils
* #param {object} obj The value to check if it is an object or not
* #returns {boolean}
*/
function isTrueObject(obj) {
return !Array.isArray(obj) && typeof obj === 'object' && !isEmpty(obj) ;
}
/**
* #memberof utils
* #param {*} val
* #returns {boolean}
*/
function isNumberLike(val) {
return isNumber(val) || regular.number.test(val);
}
/**
* #module utils
*/
module.exports = {
isTrueObject,
isNumberLike
};
If i keep the module.exports property names as-is, no docs get generated, except for a blank page for utils:
I have to do the following to get the proper documentation:
// file named utils.js
const regular = require('regular');
const isEmpty = require('lodash.isempty);
/**
* #memberof utils
* #param {object} obj The value to check if it is an object or not
* #returns {boolean}
*/
function isTrueObject(obj) {
return !Array.isArray(obj) && typeof obj === 'object' && !isEmpty(obj) ;
}
/**
* #memberof utils
* #param {*} val
* #returns {boolean}
*/
function isNumberLike(val) {
return isNumber(val) || regular.number.test(val);
}
/**
* #module utils
*/
module.exports = {
/**
* #function
* #param {object} obj The value to check if it is an object or not
* #returns {boolean}
*/
isTrueObject,
/**
* #function
* #param {*} val
* #returns {boolean}
*/
isNumberLike
};
This clearly is not ideal since the documentation is not right next above the actual function declaration and this easily leads to duplication of documentation. Is there a different way to link these and generate the same documentation?
I tried the following but all i got were links to the code itself and no actual documentation output:
/**
* #module utils
*/
module.exports = {
/** #see module:utils#isTrueObject */
isTrueObject,
/** #borrows isNumberLike as isNumberLike */
isNumberLike
};
using either #see or #borrow generates the following:
This obviously is not the desired output.
Does anyone know how to properly document this without needless duplication?
Move the #module declaration at the top of the file and replace #memberof utils with #static produces the intended result:
// file named utils.js
/**
* #module utils
*/
const regular = require('regular');
const isEmpty = require('lodash.isempty);
/**
* #static
* #param {object} obj The value to check if it is an object or not
* #returns {boolean}
*/
function isTrueObject(obj) {
return !Array.isArray(obj) && typeof obj === 'object' && !isEmpty(obj) ;
}
/**
* #static
* #param {*} val
* #returns {boolean}
*/
function isNumberLike(val) {
return isNumber(val) || regular.number.test(val);
}
module.exports = {
isTrueObject,
isNumberLike
};