我一直在使用Visual Studio的JavaScript Intellisense functionality一段时间,并且大部分都对它为标准API提供建议感到满意,但我发现我无法让Visual Studio了解配置对象(即具有多个可选或必需属性作为函数参数的单个对象)。
official JSDoc syntax表示如果某个参数具有属性,则为每个参数创建一个单独的@param
行并使用点表示法:
/**
* @param {Object} config
* @param {String} config.name
* @param {Number} config.gold
*/
function do_it(config) { ... }
但是,Visual Studio无法识别这一点 - 它将config
,config.name
和config.gold
呈现为三个单独的顶级参数。
更糟糕的是,方法体内的自动完成功能无法识别参数,更不用说它们的类型了:
在Visual Studio中看起来很接近的唯一解决方案是使用适当的文档(@constructor
和@property
标记)编写永不调用的构造函数,这使我编写了大量的死代码并且还违背了JavaScript的无类思维(这就是我首先使用配置对象的原因)。它甚至不让我写配置对象!
不仅如此,我也知道Visual Studio并不需要它。例如,当我写出对this library function的调用时,它能够收集到参数对象需要名为id
,source
和target
的属性,并建议那些我为函数的参数创建了一个对象文字时的名字 - 而没有一行文档。据推测,它来自于使用:
当然,如果这些属性不在对象上并且不是正确的类型,那么该方法会抛出异常但仍然存在。
编辑:我最近能够使用对象文字参数在我自己的代码中复制效果 - 我用一个明确定义的对象调用了一个函数,当我调用函数时它给了我Intellisense的建议我的代码中的其他地方。但我仍然没有在功能体内获得类型信息或语义访问。
Visual Studio显然理解配置对象的概念,并且正在做一些提供建议属性的逻辑。那算法是什么?如何在不破坏我的代码的情况下利用它?
答案 0 :(得分:6)
您正在使用correct JSDoc syntax,但截至今日,Visual Studio并未为具有命名属性的参数对象构建正确的IntelliSense。除了你提到的那个之外,目前还没有别的办法,但你可以描述config
对象并避免像你提到的那样编写死代码:
/**
* @typedef {object} TestConfig
* @property {string} name
* @property {number} gold
*//**
* @param {TestConfig} config
*/
function test(config) {
}
由于我们仅将此对象用于文档和自动完成目的,因此我们无需对其进行实际编码。这并不比原始语法冗长得多,并且还具有记录配置对象的好处。
关于第二个问题,您可以在sigma.js库中看到的IntelliSense来自解析函数代码本身,而不是JSDoc注释。这就是为什么当您将缩小的“sigma.min.js”构建添加到项目中时,您仍然可以使用它,其中注释已被剥离。
您可以测试此添加参数验证,类似于library function中的验证(尽管以任何其他方式访问config.name
或config.gold
也会产生相同的结果):
function do_it(config) {
if (Object(config) !== config || arguments.length !== 1) throw 'do_it: wrong arguments.';
if (typeof config.name !== 'string') throw 'config must have a name string field.';
if (typeof config.gold !== 'number') throw 'config must have a gold number field.';
...
}
结果:
以类似的方式,一旦您提供了足够的信息,将推断出正确的类型: