我一直在使用Visual Studio的JavaScript Intellisense功能一段时间,并且大部分都对它为标准API提供建议的程度感到满意,但我发现我无法让Visual Studio了解配置对象(即具有多个可选项的单个对象)或者必需的属性作为函数的参数).
该官员JSDoc语法表明,如果一个参数,预计将有属性,您创建一个单独的@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不需要它.举例来说,当我写了一个调用这个库函数,它能够收集到的参数对象需要的属性叫id
,source
和target
,当我创建了一个对象字面函数的参数建议那些名字-并没有一个单一的线文件.据推测,它来自于使用它们的简单事实:
当然,如果这些属性不在对象上并且类型不正确,那么该方法会抛出异常,但仍然如此.
编辑:我最近能够使用对象文字参数在我自己的代码中复制效果 - 我用一个明确定义的对象调用了一个函数,当我在代码中的其他位置再次调用该函数时,它给了我智能感知建议.但我仍然没有函数体内的类型信息或语义访问.
Visual Studio显然理解配置对象的概念,并且正在做一些提供建议属性的逻辑.那算法是什么?如何在不破坏我的代码的情况下利用它?
您正在使用正确的JSDoc语法,但截至目前,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"构建添加到项目中时,您仍然可以使用它,其中注释已被剥离.
您可以测试此添加参数验证,类似于库函数中的验证(尽管访问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.'; ... }
结果是:
以类似的方式,一旦您提供足够的信息,将推断出正确的类型: