I'm using the documentation package, but cannot figure out how to get it to document class properties (that aren't defined via getters and setters).
As the following just generates class documentation for SomeClass, but omits the someProperty documentation.
/**
* SomeClass is an example class for my question.
* #class
* #constructor
* #public
*/
class SomeClass {
constructor () {
this.someProperty = true // how do I document this?
}
/**
* someProperty is an example property that is set to `true`
* #property {boolean} someProperty
* #public
*/
}
An aside: the #constructor on the class jsdoc is a documentation thing.
Move the JSDoc for someProperty into the constructor where it is first defined:
/**
* SomeClass is an example class for my question.
* #class
* #constructor
* #public
*/
class SomeClass {
constructor () {
/**
* someProperty is an example property that is set to `true`
* #type {boolean}
* #public
*/
this.someProperty = true
}
}
I'm unsure if there is a way of accomplishing it with the documentation package using an approach that doesn't involve inlining the JSDocs into the constructor.
Another way is to declare them in class documentation as follows:
/**
* Class definition
* #property {type} propName - propriety description
* ...
*/
class ClassName {
constructor () {...}
...
}
You can declare properties in a class, and use #type to declare a type for them. Worked in VSCode 1.70.2 with in a plain ECMAScript Module.
class Foo {
/**
* Some bary data
* #type { BarClass }
*/
bar;
}
let f = new Foo();
f.bar; // Intellisense can tell you type and purpose
Related
I need some wrapper classes for converting values from XML to javascript and back. The setup looks like this:
/**
* #template T
* */
class Value {
/**
*
* #param {Element} valueNode
*/
constructor(valueNode) {
this.node = valueNode;
}
/** #type {T} **/
get value() {
return this.node.hasAttribute("value") ? this.convertToJS(this.node.getAttribute("value")) : null;
}
/**
* Must be overriden and provide JS object/variable from the string value
* #param {string} stringValue
* #returns {T}
*/
convertToJS(stringValue) { }
}
/**
* #class
* #extends Value<boolean>
* */
class BoolValue extends Value {
/**
* Must be overriden and provide JS object/variable from the string value
* #param {string} stringValue
* #returns {T}
*/
convertToJS(stringValue) { return stringValue == "true"; }
}
When I have an instance if BoolValue, I'd like visual studio to know that myVar.value is a boolean.
How to tell JSDoc that a class extends a templated class with specific type?
I probably did not understand the question, but
When I have an instance if BoolValue, I'd like visual studio to know that myVar.value is a boolean.
works fine with your current setup :D
I want override jsdoc for function which inheritance from base class.
the function adds parameter to base function.
parent:
export default class Base {
/**
* Function apply().
*
* Apply the hook.
*
* #param {{}} args
*
* #returns {Boolean}
*/
apply( args ) {
throw Error( 'apply() must be implanted.' );
}
}
child:
export default class Child extends Base {
/**
* how to override jsdoc and point out that i
* have added containers param?
*/
apply( args, containers ) {
}
}
#override tag will be useful i think. https://jsdoc.app/tags-override.html for reference
How do I document a member function from a father class. There is a class A with a member function Afunc(), and I am gonna document class B extends A.
I do not overwrite Afunc() in B, yet I need the function Afunc() appear in my document, how do I do it?
I wrote
/**
* description
* #function Afunc
* #memberOf A
*/
It works that appears Afunc in the document, yet there is a <static> tag at the start of the function name.
How do I solve it?
Thanks everyone.
jsdoc 3.2.2 does what you want by default. In this example, the method B.foo will automatically be documented because B extends A and does not override foo:
/**
* #class
*/
function A() {
}
/**
* Foo the flerbl.
* #param {Object} flerbl The flerbl.
*/
A.prototype.foo = function (flerbl) {
};
/**
* #class
* #extends A
*/
function B() {
}
B.prototype = new A();
Otherwise, you must use # in your #memberof tag to mark the object as an belonging to an instance of the class:
/**
* description
* #function Afunc
* #memberof A#
*/
I have a class which defines a few instance properties via Object.defineProperties and I'm having great difficulty getting JSDoc 3 to recognize that they belong to their class.
Here's a simplified version of what I'm working with:
/** #exports mymodule */
function mymodule(exports) {
/** #constructor
* #param {String} foo A foo.
* #param {String} bar A bar.
* #classdesc Has a foo and a bar.
*/
function Example(foo, bar) {
Object.defineProperties(this, {
/** A foo and a bar
* #memberof Example
*/
foobar: { enumerable: false, value: foo + bar, writable: false }
});
}
exports.Example = Example;
}
When I run JSDoc, I get output for mymodule, Example, foo, and bar, but not foobar. If I remove the #memberof tag for foobar, it get registered as a global. I've tried #memberof mymmodule~Example, adding #lends to both the Object.defineProperties call and the object passed to it, and converting it to Object.defineProperty, but the results don't change.
How can I document foobar as belonging to Example?
After digging through every example I could find, I finally assembled the necessary incantation — #memberof is indeed the trick, but JSDoc seems to require that modules being used in namepaths be explicitly marked as such. The following worked perfectly:
/** A foo and a bar
*
* #type String
* #instance
* #memberof module:mymodule~Example
*/
You could also try the #lends annotation in place of #memberOf like this :
Object.defineProperties(this, /** #lends Example# */{
/** A foo and a bar */
foobar: { enumerable: false, value: foo + bar, writable: false }
});
Don't forget the sharp symbol after the class name to tell jsdoc members are instance members and not static members.
After fiddling around for many hours, I finally got it to work with #memberOf!. Note the uppercase "O" and the bang "!"
/**
* Description
* #memberOf! MyClass
* #type {String}
*/
var myString;
In case you want to use defineProperty instead, a #type annotation is sufficient (at least for IntelliJ to infer the proper type for the property):
/** #type SomeType */
Object.defineProperty(this, "someProperty", {
get: () => new SomeType()
});
I am trying to understand the JSDoc style for documenting JavaScript that is used with the JavaScript Closure Compiler. I have the JavaScript code below
// ==ClosureCompiler==
// #compilation_level ADVANCED_OPTIMIZATIONS
// ==/ClosureCompiler==
(function(){
/**
* #type Array.<string>
* #private
*/
var sb = [];
/**
* #const
* #type{{append: function(string): SingletonStringBuffer, toString: function(): string}}
*/
window['SingletonStringBuffer'] = {
/**
* #param {string} text
* #return {SingletonStringBuffer}
*/
append: function(text){
sb.push(text);
return SingletonStringBuffer;
},
/**
* #return {string}
*/
toString: function(){
return sb.join("");
}
};
}());
When I do an advanced compile on this code I am receiving 2 warnings.
JSC_TYPE_PARSE_ERROR: Bad type annotation. Unknown type SingletonStringBuffer at line 10 character 35
* #type{{append: function(string): SingletonStringBuffer, toString: function()...
^ JSC_TYPE_PARSE_ERROR: Bad type annotation. Unknown type SingletonStringBuffer at line 15 character 11
* #return {SingletonStringBuffer}
^
The function append returns a deference to the encapsulating object. The variable that it is returning ,SingletonStringBuffer, is declared... so I am not sure what is wrong or how to correct it.
You haven't created a named type as far as the compiler is concerned. For this case, I would expect you to create an interface:
/** #interface */
function StringBuffer() {
}
/**
* #param {string} text
* #return {StringBuffer}
*/
StringBuffer.prototype.append;
etc
This can be declared either in the code (if you are using advanced mode it will be stripped) or in your extern files (if you want the type without the code in simple mode).
You can then use it like so (in your case):
(function(){
/**
* #type Array.<string>
* #private
*/
var sb = [];
/**
* #const
* #type {StringBuffer}
*/
window['SingltonStringBuffer'] = {
/**
* #param {string} text
* #return {StringBuffer}
*/
append: function(text){
sb.push(text);
return SingltonStringBuffer;
},
/**
* #return {string}
*/
toString: function(){
return sb.join("");
}
};
}());
singletons work differently in closure. I have not seen an explicit annotation for it, but the compiler (in advanced mode) has some understanding of certain built-in functions
Singletons would be declared via the goog.addSingletonGetter function, here is a code sample
/**
* #constructor
* #extends {path.to.BaseClass}
*/
path.to.MyClass = function() {
goog.base(this);
};
goog.inherits(path.to.MyClass, path.to.BaseClass);
goog.addSingletonGetter(path.to.MyClass);
and that be it.
PS
you are getting the bad annotation because {SingltonStringBuffer} is never declared as a class.
PPS.
Some rambling on post the fact.
I suspect (but this is untested) that making the constructer private might work. Notice the trailing underscore in the example
/**
* #private -> NOTE THIS IS IN NO WAY VERIFIED
* #constructor
* #extends {path.to.BaseClass}
*/
path.to.MyClass_ = function() {
goog.base(this);
};
goog.inherits(path.to.MyClass, path.to.BaseClass);
goog.addSingletonGetter(path.to.MyClass);