Documenting arrays in JSDoc typedefs for VS Intellisense

In my VS2015 JavaScript app, I have a JSON object that I get from a REST API that I have documented using JSDoc @typedef comments:

/**
 * @typedef {Object} JSON_Response
 * @property {Number} id
 * @property {String} name
 * @property {JSON_Response_Tag} tag
 */

/**
 * @typedef {Object} JSON_Response_Tag
 * @property {Number} id
 * @property {String} color
 */

When I reference this type in JSDoc comments on the methods that consume these JSON objects, I can get Intellisense documentation just fine:

/**
 * @param {JSON_Response} response
 */
function process_response(response) {
  // process response here...
}

However, I simply cannot get this to work with arrays – when I attempt to index the array, I get the “yellow triangles” menu that happens when VS can’t get Intellisense context for you:

/**
 * @typedef {Object} JSON_Response
 * @property {Number} id
 * @property {String} name
 * @property {JSON_Response_Tag[]} tags
 */

/**
 * @param {JSON_Response} response
 */
function process_response(response) {
  response.tags[0]. // no intellisense here
}

JSDoc’s other recommended method, using {Array.<JSON_Response>}, informs VS that response is an Array but does not give Intellisense for anything under that. Microsoft’s own XML comments do provide this capability, but only for function parameters – I can’t reach inside the objects, nor would I like to do so because I’d have to add this documentation every time the function is called.

Is there any way to document arrays with their underlying types in JavaScript’s VS Intellisense?

If I have to write code, I want to minimize the side effects / be able to factor it out of the release.

Solution #1:

Okay, so I actually read your question this time (sorry, I was in the middle of something earlier).

Issue

Visual Studio will not recognize the JSDoc syntax you are using to define the type of element within your array—at least not where intellisense is concerned.

Solution

XML is the solution here. You may be aware of this, but you can use JSDoc tags in conjunction with XML comments to circumvent their individual limitations. I’m not sure what tags and attributes you were using when you ran your tests earlier, but here is the correct implementation of your code:

/**
 * @typedef {Object} JSON_Response
 * @property {Number} id
 * @property {String} name
 * @property {JSON_Response_Tag} tag
 */

/**
 * @typedef {Object} JSON_Response_Tag
 * @property {Number} id
 * @property {String} color
 */

/**
 * @param {JSON_Response[]} response
 */
function process_response(response) {
    /// <param name="response" type="Array" elementType="JSON_Response"></param>

   response[0]. // intellisense works here
}

DOCUMENTING NESTED PARAMETER PROPERTIES FOR INTELLISENSE

Regarding your comment and the edits you made to your question, you can specify nested property types of parameters using the value attribute of the param XML comment. The term “value” is a little misleading, because according to the MSDN documentation, it isn’t used to actually specify a value but rather a value type. See below:

/**
 * @typedef {Object} JSON_Response
 * @property {Number} id
 * @property {String} name
 * @property {JSON_Response_Tag[]} tag
 */

/**
 * @typedef {Object} JSON_Response_Tag
 * @property {Number} id
 * @property {String} color
 */

/// <summary name="JSON_Response_Tag" type="Object">my test summary</summary>
/// <field name="id" type="Number">testid</field>
/// <field name="color" type="String">testcolor</field>

/**
 * @param {JSON_Response} response
 */
function process_response(response) {
    /// <param name="response" type="JSON_Response" value="{id:0,name:"",tag:[{id:0,color:""}]}"></param>

    response.tag[0]. // intellisense works here
}

Regarding Companynerd225’s alternate solution

I’m not entirely sure that categorizing JSON objects as classes instead of types is the most accurate method here. Also, although I may not know the proper terms for it, I’m pretty sure a function returning {id:0} is not the same as a function returning this. See below:

Class vs. Objects

Not to mention, you would end up filling your JSDoc “Classes” section with types. By default, it would look like this in your navigation:

Malformed JSDoc Classes Section


Respondent: TheHansinator

Solution #2:

It seems counter-intuitive, but the best way to get documentation on your JSON types, rather than bothering with the limitations of XML comments and Intellisense’s limited ability to parse JSDoc, is to actually write constructors that produce your types, then reference it so that it is only parsed for documentation purposes.

In other words, have constructors in your JavaScript that look like this:

/**
 * @constructor {Object} JSON_Response
 * @property {Number} id
 * @property {String} name
 * @property {JSON_Response_Tag[]} tags
 */
function JSON_Response(){
  return {
    id: 0,
    name: "",
    tags: [new JSON_Reponse_Tag()]
  }
}

/**
 * @constructor {Object} JSON_Response_Tag
 * @property {Number} id
 * @property {String} color
 */
function JSON_Response_Tag(){
  return {
    id: 0,
    color: "#000000"
  }
}

You don’t necessarily need all of the individual object types defined out: you can use whatever you’d like. You can even copy and paste a sample of your JSON output. You only need to divide out classes if you intend to store inner objects in other variables.

And then, instead of actually including the JavaScript file in your page, you can put all of these JSON constructors in a separate file and put an XML reference directive

/// <reference path="~/path/to/schema_file.js" />

at the top of your consuming JavaScript files – Visual Studio will run the code for the sole purpose of providing documentation.

Respondent: Lopsided

The answers/resolutions are collected from stackoverflow, are licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0 .

Leave a Reply

Your email address will not be published.