I am using #typedef to define some custom types, with #property items.
When doing the same for a class I can just use {#link MyClass#property} to reference the property.
But for some reasons {#link MyType#property} does not resolve.
Is this a bug or is there a different way to reference such properties?
My usage example:
/**
* #typedef helpers.Column
*
* #property {String} name
*/
/**
* This one resolves correctly: {#link helpers.Column}
*
* This one does not resolve: {#link helpers.Column#name}
*/
Related
Given a type definition:
/**
* #typedef {object} Foo
* #property {string} someString
* #property {number} someNumber
*/
is there a way to create another type definition that includes only a subset of the parent's properties? E.g. the effective result would be something like:
/**
* #typedef {object} Bar
* #property {string} someString
*/
but using someString as it was already defined in Foo
I need to add a function attached to a node in this way:
myElement = querySelector('#myElement');
myElement.moveMe = () =>{
//move Me Code;
}
But I do not know how to document this function (and also prevent lint errors), I tried use #extends with a #typedef but it says that it just works with constructors.
I might suggest that the right way to do this would be to create an object with {el: myElement, moveMe: ()=>{}} myself, but if you must extend, it looks like this:
/**
* #constructor
* #extends {HTMLElement}
*/
const NewType = function() {};
/** #type {function()} */
NewType.prototype.moveMe = function(){};
/** #type {NewType} */
const myElement = /** #type {NewType} */ (document.querySelector('body div'));
myElement.moveMe = () =>{
//move Me Code;
console.log('dont remove me');
}
Error free
(Not sure about your stack, just noting my 2C from recent (2019-Q1) personal VSCode JSDoc struggles.)
In theory, it seems it should be possible to use simple #typedef with "parent" type declaration: (this does not work)
/**
* #typedef {HTMLElement} movableElement
* #property {function} moveMe
*/
/** #type movableElement */
var myElement = document.querySelector('#myElement');
myElement.moveMe; // NOPE, not present for some reason :(
myElement.tabIndex; // ok, this is from HTMLElement
Closest to intention of extending native HTML elements with custom properties was to & "Intersection Type notation" I learned about from this comment either using helper type:
/**
* #typedef movable
* #property {function} moveMe
*/
/**
* #typedef {HTMLElement & movable} movableElement
*/
/** #type movableElement */
var myElement = document.querySelector('#myElement');
myElement.moveMe; // ok
myElement.tabIndex; // ok (HTMLElement properties are present as well)
Or even without helper type, with direct intersection:
/**
* #typedef {HTMLElement & {moveMe: function}} movableElement
*/
/* ... */
Strangely, any #property declaration added to such extended type seems to be completely ignored (just like our property in the first failed attempt, I'm still not sure why).
I've been struggling to achieve something similar - extend HTMLElement with some hacky custom properties in JavaScript in VSCode - and after exhaustive SO / github / docs diving this workaround-ish solution quite worked for me.
I have a function with a huge list of options:
/**
* Show dialog in a blocking manner.
*
* #param {object} opts
* #param {string} opts.msg "Body" of the dialog.
* #param {number} opts.timeout Seconds - floating point values are rounded. (ActiveX imposes this)
* #param {string} opts.title Title of the dialog.
* #param {number} opts.icon Use constants for this. (See docs)
* #param {number} opts.buttons Use constants for this. (See docs)
* #param {number} opts.defaultButton Use constants for this. (See docs)
* #returns {number} Use our constants to check for what the user chose.
*/
const showSync = (opts) => {
...
}
But I also have a non-blocking version of this function obviously takes the same options and returns a Promise. It seems quite dirty to copy/paste the docs, as this will decrease maintainability and likelihood for accidental inconsistency.
So what would be great is something like the following:
/**
* Shows dialog in a non-blocking manner.
*
* #inheritdoc showSync
* #returns {Promise<number>} Use our constants to check for what the user chose.
*/
const show = (opts) => {
...
}
Is this possible somehow?
[UPDATE]
This is not a duplicate of JSDoc for reused Function interface because that question is merely about reusing the same definition, while this one is about reusing but also partly overwriting that definition. And hence, the answer there does not answer the question here.
I think the best way to do that with jsdoc is something like this:
/**
* Options for showing a dialog.
* #typedef {Object} ShowOptions
* #property {string} msg "Body" of the dialog.
* #property {number} timeout Seconds - floating point values are rounded. (ActiveX imposes this)
* #property {string} title Title of the dialog.
* #property {number} icon Use constants for this. (See docs)
* #property {number} buttons Use constants for this. (See docs)
* #property {number} defaultButton Use constants for this. (See docs)
*/
/**
* Show dialog in a blocking manner.
*
* #param {ShowOptions} opts
* #returns {number} Use our constants to check for what the user chose.
*/
const showSync = (opts) => {...}
/**
* Shows dialog in a non-blocking manner.
*
* #param {ShowOptions} opts
* #returns {Promise<number>} Use our constants to check for what the user chose.
*/
const show = (opts) => {...}
You could take it a step further and apply a similar concept to the return value as well:
/**
* Use our constants to check for what the user chose.
* #typedef {number} ShowResult
*/
/**
* Show dialog in a blocking manner.
*
* #param {ShowOptions} opts
* #returns {ShowResult}
*/
const showSync = (opts) => {...}
/**
* Shows dialog in a non-blocking manner.
*
* #param {ShowOptions} opts
* #returns {Promise<ShowResult>}
*/
const show = (opts) => {...}
I have jsdoc'ed my function like this:
/**
* #typedef {Object} SearchTerms
* #property {string} what
* #property {string} where
* #property {boolean} online
*/
/**
* From react-router params, which are URL encoded, it figures out the "what", "where", and "online" terms.
*
* #export
* #param {Object} params The `params` field from react-router component props.
* #param {string} [params.what="Everything"] The subject of users search.
* #param {string} [params.where] The location of users search.
* #returns {SearchTerms}
*/
export function getSearchTerms(params) {
However the params key is not properly expanded on hover of the function:
Is there anyway for it to properly expand params argument? I was hoping for it to show:
Except that it should also show that it is optional with question mark. And as I type the argument, it should show the description of that argument like this:
The problem is that you've specified the type of your params param as Object. You should break out your params as second #typedef:
/**
* #typedef SearchOptions
* #property {String} [what="Everything"] The thing
* #property {String} [where] A place
*/
/**
* #param {SearchOptions} params
*/
function getSearchTerms(params){ ... }
Using a named interface like this, VSCode should show the arguments in Intellisense like you're looking for.
How can I document possible configuration properties in function argument in JSDOC:
/**
* N level expectimax AI.
*
* #param {object} cfg config
* cfg.minimaxDepth - limit for minimax search
* cfg.expectiDepth - limit for expectimax search
* cfg.weightFn - position weight function
*
* #constructor
*/
function expectimaxAI(brdEngine, cfg) { ... }
Which markup is to use for cfg.minimaxDepth (cfg.*) parameters?
Is it possible to document synthetic aiCfg type and put reference to it as:
* #param {aiCfg} cfg config
or somehow else?
After reading official JSDoc 2.x docs I make some hack:
/**
* #name BlindWeightRandomCfg
* #function
* #param {number} left weight
* #param {number} right weight
* #param {number} up weight
* #param {number} down weight
*/
and refer to non-existing function as:
/**
* Blind weight random AI.
*
* #param {Board} brdEngine board engine from board.js
* #param {BlindWeightRandomCfg} cfg configuration settings
* #constructor
*/
ai.BlindWeightRandom = function(brdEngine, cfg) { ... }
Now argument cfg - clickable to definition of BlindWeightRandomCfg!
UPDATE Another possibility for JSDoc 2.x:
/**
* #name BlindWeightRandomCfg
* #namespace
* #property {number} left weight
* #property {number} right weight
* #property {number} up weight
* #property {number} down weight
*/
and for JSDoc 3.x:
/**
#typedef PropertiesHash
#type {object}
#property {string} id - an ID.
#property {string} name - your name.
#property {number} age - your age.
*/
/** #type {PropertiesHash} */
var props;
Seems that #typedef is a solution. Please see other variants and at official docs.