Как документировать объекты конфигурации 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.';
    ...
}

Результаты в:

введите описание изображения здесь

Аналогичным образом, как только вы предоставите достаточную информацию, будет выведен правильный тип:

введите описание изображения здесь