Как документировать объекты конфигурации JavaScript в Visual Studio Intellisense
Я уже давно использовал 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
как три отдельных параметра верхнего уровня.
![do_it() регистрирует три отдельных параметра]()
Хуже того, функции AutoComplete внутри тела метода не распознают параметры, а тем более их типы:
![Попытка доступа к методам config.name дает желтые треугольники и никакой помощи.]()
Единственное решение, которое, похоже, даже близко работает в Visual Studio, заключается в том, чтобы писать никогда не называемые конструкторские функции с соответствующей документацией (теги @constructor
и @property
), что заставляет меня писать много мертвого кода, а также идти против Бесполезный менталитет JavaScript (именно поэтому я использую объекты конфигурации в первую очередь). Это даже не позволяет мне писать объект конфигурации!
Не только это, но я также знаю, что Visual Studio не нуждается в этом. Например, когда я написал вызов этой библиотечной функции, он смог получить, что объект аргумента нуждается в свойствах, называемых id
, source
и target
, и предложили эти имена, когда я создал объектный литерал для аргумента функции, и без отдельной строки документации. Предположительно, это исходило из простого факта, что они использовались:
![Visual Studio автоматически запускает эти три свойства без каких-либо комментариев документации]()
Конечно, метод действительно генерирует исключения, если эти свойства не находятся на объекте и не имеют нужного типа, но все же.
EDIT:. Недавно мне удалось воспроизвести эффект в моем собственном коде несколько с параметрами литерала объекта - я назвал одну функцию с четко определенным объектом, и он дал мне предложения Intellisense, когда я вызвал функцию снова в другом месте моего кода. Но у меня до сих пор нет информации типа или семантического доступа внутри тела функции.
Visual Studio явно понимает концепцию объектов конфигурации и делает некоторую логику для предоставления предлагаемых свойств. Что это за алгоритм? И как я могу использовать его без искажения моего кода?
Ответы
Ответ 1
Вы используете правильный синтаксис JSDoc, но на сегодняшний день Visual Studio просто не создает правильные объекты IntelliSense для объектов с именованными свойствами, В настоящее время нет другого пути вокруг этого, кроме того, на который вы ссылаетесь, но вы можете описать объект config
на месте и не записывать мертвый код, как вы уже упоминали:
/**
* @typedef {object} TestConfig
* @property {string} name
* @property {number} gold
*//**
* @param {TestConfig} config
*/
function test(config) {
}
Поскольку мы используем этот объект только для документации и автозаполнения, нам не нужно на самом деле его кодировать. Это не намного более подробный, чем оригинальный синтаксис, и имеет преимущество в том, что объект конфигурации также документирован.
О вашем втором вопросе, IntelliSense, который вы можете увидеть для библиотеки sigma.js, получена при разборе тела самого кода функции, а не комментарии 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.';
...
}
Результаты в:
![введите описание изображения здесь]()
Аналогичным образом, как только вы предоставите достаточную информацию, будет выведен правильный тип:
![введите описание изображения здесь]()