Тип JSDoc для возвращенных экземпляров класса

Я использую Node.js с двумя модулями и одним зависящим от них скриптом:

lib/Bar.js

module.exports = class Bar {
  // ..
};

lib/Foo.js

const Bar = require('./Bar.js');

module.exports = class Foo {
  /**
   * @return {Bar} A Bar instance
  */
  get someBar() {
    return new Bar();
  }
};

main.js

const Foo = require('./lib/Foo.js');

checkFoo(new Foo());

/**
 * @param {Foo} foo A Foo instance
*/
function checkFoo(foo) {
  foo. // I get suggestions for Foo properties
  foo.someBar. // I get suggestions for Bar properties

  checkBar(foo.someBar);
}

/**
 * @param {Bar} bar a Bar instance
*/
function checkBar(bar) {
  bar. // I get no suggestions!
}

Мой редактор кода Visual Studio Code использует IntelliSense, чтобы дать пользователю предложения о свойствах Foo и Bar, которые правильно работают внутри метода checkFoo, поскольку тип foo объявлен как объект Foo, а тип foo.someBar объявлен в классе Foo как объект. Bar объект.

Но как только я передаю этот экземпляр Bar другому методу (checkBar), тип Bar не распознается (вероятно, потому что мне не нужен модуль). Есть ли в JSDoc специальный синтаксис для указания типа, объявленного в другом модуле? Или это просто проблема с VSCode?


person Felix Edelmann    schedule 04.08.2017    source источник
comment
Помогает ли это usejsdoc.org/tags-typedef.html?   -  person Lazyexpert    schedule 04.08.2017
comment
@Lazyexpert К сожалению, нет. Все свойства в Bar задокументированы с допустимыми комментариями JSDoc, и, поскольку предложения были показаны в методе checkFoo, ссылка действительно работает. Мне только интересно, как заставить предложения работать в checkBar.   -  person Felix Edelmann    schedule 04.08.2017


Ответы (2)


Вам больше не нужно импортировать тип (например, это может привести к поломке линтеров). Вместо этого вы можете указать VSCode (на самом деле, TypeScript), используя синтаксис типа импорта:

const Foo = require('./lib/Foo.js');

...

/**
 * @param {import('./lib/Bar.js').default} bar a Bar instance
 */
function checkBar(bar) {
    ...
}

Обратите внимание, что ключевое слово по умолчанию требуется только потому, что это экспорт по умолчанию.

person Bruno Brant    schedule 21.08.2019
comment
Спасибо, это то, что я искал. Просто добавлю, что вам не нужно .default с модулями CommonJS (как в примере в моем вопросе). Однако этот подход пока не работает в VSCode с .mjs файлами. - person Felix Edelmann; 01.09.2019

Ваше подозрение верно. В настоящее время вам также необходимо импортировать Bar, чтобы использовать его тип в jsdoc:

const Foo = require('./lib/Foo.js');
const Bar = require('./lib/Bar.js');

...

/**
 * @param {Bar} bar a Bar instance
 */
function checkBar(bar) {
    ...
}

Мы отслеживаем поддержку JSDoc-эквивалента require или import здесь: https://github.com/Microsoft/TypeScript/issues/14377

person Matt Bierner    schedule 04.08.2017