在VS Intellisense的JSDoc typedef中记录数组

时间:2016-01-18 21:10:23

标签: javascript getjson javascript-intellisense

在我的VS2015 JavaScript应用程序中,我有一个JSON对象,我从使用JSDoc @typedef注释记录的REST API中获取:

/**
 * @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
 */

当我在使用这些JSON对象的方法的JSDoc注释中引用此类型时,我可以很好地获得Intellisense文档:

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

然而,我根本无法使用数组 - 当我尝试索引数组时,我得到了"黄色三角形"当VS无法为您获取Intellisense上下文时发生的菜单:

/**
 * @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的其他推荐方法,使​​用{Array.<JSON_Response>},通知VS response是一个数组但不提供智能感知。微软自己的XML注释确实提供了这种功能,但仅限于功能参数 - 我无法覆盖对象内部,也不愿意这样做,因为我每次都必须添加此文档该函数被调用。

有没有办法在JavaScript的VS智能感知中使用基础类型来记录数组?

如果我必须编写代码,我希望尽量减少副作用/将其从发布中分解出来。

2 个答案:

答案 0 :(得分:4)

好的,所以这次我实际上读了你的问题(对不起,我早些时候处于中间位置)。

问题

Visual Studio将无法识别您用于定义数组中元素类型的JSDoc语法 - 至少不会涉及intellisense。

解决方案

XML就是这里的解决方案。您可能已经意识到这一点,但您可以将JSDoc标记与XML注释结合使用,以规避其个别限制。我不确定您之前运行测试时使用的标记和属性,但这是您的代码的正确实现:

/**
 * @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
}

记录智能的嵌套参数

关于您对您的问题所做的评论和编辑,您可以使用value XML注释的param属性指定参数的嵌套属性类型。术语“值”有点误导,因为根据MSDN documentation,它不是用于实际指定值而是用于值类型。见下文:

/**
 * @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
}

关于Companynerd225的替代解决方案

我不完全确定将JSON对象分类为类而不是类型是最准确的方法。此外,虽然我可能不知道它的正确用语,但我很确定返回{id:0}的函数与返回this的函数不同。见下文:

Class vs. Objects

更不用说,您最终会使用类型填充JSDoc“Classes”部分。默认情况下,它会在您的导航中显示如下:

Malformed JSDoc Classes Section

答案 1 :(得分:1)

这似乎是违反直觉的,但是获取JSON类型文档的最佳方法,而不是困扰XML注释的局限性和Intellisense解析JSDoc的能力有限,是实际编写构造函数产生你的类型,然后引用它,以便它只被解析用于文档目的。

换句话说,JavaScript中的构造函数看起来像这样:

/**
 * @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"
  }
}

您不一定需要定义所有单独的对象类型:您可以使用您喜欢的任何内容。您甚至可以复制并粘贴JSON输出的样本。如果您打算将内部对象存储在其他变量中,则只需要分出类。

然后,您可以将所有这些JSON构造函数放在单独的文件中并放入XML引用指令

,而不是在页面中实际包含JavaScript文件。
/// <reference path="~/path/to/schema_file.js" />

在您使用的JavaScript文件的顶部 - Visual Studio将运行代码,仅用于提供文档。