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

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
}
}

Related

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 }
}
}

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

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)

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
};

Doctrine ODM with MongoDB need both reference mappings set

I'm having the following situation in doctrine ODM with MongoDB and Symfony 2.x
Class A:
class Port extends AbstractEthernetPort
{
/** Other Fields **/
/**
* Owning the reference
* #MongoDB\ReferenceOne(
* targetDocument="\xxx\AbstractObject",
* cascade="all",
* inversedBy="ports"
* )
*/
protected $device;
/** SETTER and GETTERS **/
}
Class B:
class Device extends AbstractObject
{
/** Other Fields **/
/**
* #MongoDB\ReferenceMany(
* targetDocument="\xxx\AbstractEthernetPort",
* cascade="all",
* mappedBy="device"
* )
*/
protected $ports = array();
/** SETTER and GETTERS **/
}
These both classes are linked togehter with ReferenceOne and ReferenceMany. The code has beend slightly changed for this post.
This are the both versions of the testcase. The First does not work, the second does:
public function testPorts() {
$dm = self::$container->get('doctrine_mongodb')->getManager();
$sideASwitch = new Device();
$sideASwitch->setName("Switch01");
$copper1 = new Port();
$copper1->setDescription("Copper Port");
$copper2 = new Port();
$copper2->setDescription("Copper Port");
$sideASwitch->setPorts(array($copper1, $copper2));
$dm->persist($sideASwitch);
$dm->flush();
$x = $dm->getRepository("Device")->findOneBy(array());
\Doctrine\Common\Util\Debug::dump($x,1);
}
The query at the end returns an ports array with 0 content.
public function testPorts() {
$dm = self::$container->get('doctrine_mongodb')->getManager();
$sideASwitch = new Device();
$sideASwitch->setName("Switch01");
$copper1 = new Port();
$copper1->setDescription("Copper Port");
$copper2 = new Port();
$copper2->setDescription("Copper Port");
// ADDITIONAL
$copper1->setDevice($sideASwitch);
$copper2->setDevice($sideASwitch);
$sideASwitch->setPorts(array($copper1, $copper2));
$dm->persist($sideASwitch);
$dm->flush();
$x = $dm->getRepository("Device")->findOneBy(array());
\Doctrine\Common\Util\Debug::dump($x,1);
}
This Query returns an ports array with 2 objects in it...
Is this the normal behaviour in Doctrine ODM or are am i doing something wrong?
Thanks for any help
This is the expected behavior. Calling $sideASwitch->setPorts(array($copper1, $copper2)); has no effect because ports is the mapped side.
As a convenience, I often do something like the following on the mapped (Device) side:
public function setPorts(array $ports)
{
foreach($ports as $port) {
$port->setDevice($this);
}
return $this;
}