Как документировать javascript функцию высшего порядка?

У меня есть следующая функция более высокого порядка для обертывания конструкторов:

/**
 * Wrapper for calling constructor with given parameters
 *
 * @param {Class} Cls
 * @returns {function} Wrapper on constructor which creates an instance of given Class
 */
function constructorWrapper(Cls) {
    return (...args) => new Cls(...args);
}

Так что, если у меня есть класс MyClassЯ могу сделать следующее:

exports.MyClass = MyClass;
exports.myClass = constructorWrapper(MyClass);

Теперь класс может быть создан двумя способами после импорта:

const instance1 = new MyClass(param1, param2);
const instance2 = myClass(param1, param2);

В VScode, instance1 будет иметь поддержку IntelliSense, но instance2 не будет. Как мне документировать функцию / экспорт, чтобы объекты, созданные с помощью обертки, распознавались как экземпляры класса?

1 ответ

Решение

Вы можете сделать IntelliSense доступным, указав тип myClass:

/** @type {function(T1, T2): MyClass} */
exports.myClass = constructorWrapper(MyClass);

Если вы хотите аннотировать constructorWrapper Сам по себе, однако, это невозможно с VSCode 1.11.1 (с TypeScript 2.2). Хотя JSDoc поддерживает дженерики:

/**
 * Wrapper for calling constructor with given parameters
 *
 * @param {function(new:T, ...*)} Cls The class constructor.
 * @returns {function(...*): T} Wrapper of the class constructor
 * @template T
 */
function constructorWrapper(Cls) {
    return (...args) => new Cls(...args);
}

и выведенный тип действительно правильный:

code> функция constructorWrapper <T> (Cls: new (... arg1: any []) => T): (... arg0: any []) => T </ code функция constructorWrapper (Cls: new (... arg1: any []) => T): (... arg0: any []) => T

Каким-то образом два "Т" становится отключенным, делая myClass = constructorWrapper(MyClass) принять тип подписи (...arg0: any[]) => T, Какие T? Ну, мы не знаем, относиться к этому как any и нет IntelliSense тогда.

code> myClass: (... arg0: any []) => T </ code myClass: (... arg0: any []) => T

Основанный на JSDoc VSCode IntelliSense основан на TypeScript, и я думаю, что это ошибка в обработке TypeScript @template по состоянию на 2.2.

Если вы не ограничены разработкой только для ES6, я рекомендую переписать ее полностью в TypeScript. Тогда вы получите ожидаемый IntelliSense, плюс безопасность типов и многие другие преимущества.

Обратите внимание, что, поскольку TypeScript 2.2 не поддерживает универсальные переменные, все же аргументы не могут быть идеально переданы, поэтому ввод к myClass не может быть проверено типом. Это означает, что вам все еще нужно вручную аннотировать тип myClass чтобы получить идеальную информацию.

Другие вопросы по тегам