6

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

/**
 * @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 的其他推荐方法 using{Array.<JSON_Response>}通知 VS 这response是一个数组,但不提供 Intellisense 下的任何内容。Microsoft 自己的 XML 注释确实提供了这种功能,但仅限于函数参数 - 我无法进入对象内部,我也不想这样做,因为每次调用函数时我都必须添加此文档。

有没有办法在 JavaScript 的 VS Intellisense 中记录数组及其底层类型?

如果我必须编写代码,我想尽量减少副作用/能够将其排除在发布之外。

4

2 回答 2

5

好的,所以这次我实际上阅读了您的问题(对不起,我之前在做某事)。

问题

Visual Studio 将无法识别您用于定义数组中元素类型的 JSDoc 语法——至少在涉及智能感知的情况下不会。

解决方案

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
}

记录用于 INTELLISENSE 的嵌套参数属性

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

/**
 * @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。见下文:

类与对象

更不用说,您最终会用类型填充您的 JSDoc“类”部分。默认情况下,它在您的导航中看起来像这样:

格式错误的 JSDoc 类部分


于 2016-01-18T21:20:23.087 回答
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 将运行代码,其唯一目的是提供文档。

于 2016-01-19T16:49:50.187 回答