Как аннотировать класс ES5 с помощью JSDoc @template в VSCode, чтобы предотвратить ошибки checkJS? - PullRequest
0 голосов
/ 16 ноября 2018

Я пытаюсь аннотировать все мои функции JavaScript и свойства класса с помощью JSDoc, чтобы включить надлежащую проверку типов с использованием TypeScript и опции checkJS.

Однако, поскольку я хочу поддерживать старые браузеры (IE9) и не хочу переносить код с помощью Babel, мне нужно использовать JavaScript эпохи ES5 и не могу использовать «класс» для определения класса. Поэтому мне нужно прибегнуть к простым старым прототипам функций.

В проекте, над которым я работаю, у меня есть следующий класс:

/**
 * A condition class, executes a set function on results that meet their required conditions.
 * @class
 * @template T
 */
function Condition()
{
  /** @type {{condition?: boolean, result: T}[]} A list of conditions to execute. */
  this.list = new Array();
}

/** 
 * Adds a condition
 * @param {{condition: boolean, result: T}} condition The object with the condition and the result to be sent to the executing function.
 */
Condition.prototype.add = function(condition)
{
  this.list.push(condition);
}

/**
 * Executes the added conditions.
 * @param {function(T):void} action The function to be executed when a condition is true.
 */
Condition.prototype.execute = function(action)
{
  this.list.forEach(function(condition) { if(condition.condition) action(condition.result); });
}

В этом классе элемент result всегда имеет один и тот же тип в одном и том же экземпляре класса, что делает его идеальным вариантом использования шаблона, как видно из кода.

Однако, когда я пытаюсь использовать класс, используя, например, следующий код:

var conditionList = /**@type {Condition<string>} */(new Condition());
conditionList.add({ condition: true, result: 'yes' });
conditionList.execute(function(value) { console.log(value); });

Я получаю следующую ошибку в VSCode:

Type 'string' is not assignable to type 'T'. The expected type comes from property 'result' which is declared here on type '{ condition: boolean; result: T; }'

Когда я наводю мышь на conditionList, всплывающее окно говорит: var conditionList: typeof Condition.

Изменение объявления conditionList на var /**@type {typeof Condition<string>} */(new Condition()); также не работает и выдает ошибку о том, что typeof Condition нельзя преобразовать в typeof Condition.

Поэтому я понятия не имею, что делать, чтобы шаблон работал, сохраняя при этом стиль объявления класса ES5.

Однако, если я преобразую код в класс в стиле ES6 (class Condition), и я оставлю аннотации такими, какие они есть, тогда код работает правильно. В этом случае при наведении курсора на conditionList появляется всплывающее окно с текстом var conditionList: Condition<string> и ошибок нет.

Есть ли способ получить такое же поведение, используя классы стилей ES5? Я что-то пропустил? Или это может быть что-то нереализованное в контроллере TypeScript VSCode?

1 Ответ

0 голосов
/ 17 ноября 2018

Кажется, это ошибка, и у нее открытая проблема в Github.Кажется, это не будет исправлено, пока не будет выпущен TypeScript 3.3, к сожалению:

https://github.com/Microsoft/TypeScript/issues/26883

...