Проверка типов выдает ошибку в VSCode в обычном JS-файле

#javascript #typescript

#javascript #typescript

Вопрос:

Допустим, у меня есть HTML-элемент следующим образом:

 <progress value="1" max="10" id="site_progress"></progress>
  

VSCode показывает проблему («Свойство «max» не существует для типа «Элемент»»), если я выбираю этот элемент следующим образом:

 const progress = document.querySelector('#site_progress');
progress.max = 9;
  

Проблем не будет, если я выберу через селектор элементов:

 const progress = document.querySelector('progress');
progress.max = 9;
  

Могу ли я сделать что-то вроде утверждения типа, чтобы избежать такого поведения, или каковы хорошие методы решения этой проблемы в обычном javascript?

Комментарии:

1. queryselector может возвращать любой тип элемента, который вы предоставляете id или class и т.д. Поэтому вам нужно будет выполнить приведение вручную..

2. вы пробовали getElementById

3. Typescript не может проверить ваш HTML. Он может только вывести, что если селектор progress равен, то результат равен HTMLProgressElement | null . Это будет работать и для любого другого элемента. div => HTMLDivElement input , = HTMLInputElement > и т.д… Но если вы добавите к нему какой-либо другой селектор, он не сможет этого сделать.

4. Что немного странно, так это то, что even input#id не сообщает TS, что выбранный элемент является a HTMLProgessElement , насколько я тестировал.

Ответ №1:

Лично я бы просто перешел на TS, но даже тогда вам все равно нужно будет выполнить приведение. Чтобы привести тип в JS, вы можете сделать ->

 /** @type HTMLProgressElement */
const progress = document.querySelector('#id');
progress.max = 9;
  

В Typescript это было бы похоже на ->

 const progress = document.querySelector('#id') as HTMLProgressElement;
progress.max = 9;
  

Еще одна приятная функция, вы можете создавать защиту типов, и это также помогает компилятору.

например, это ниже будет работать как в TS, так и в JS.

 const progress = document.querySelector('#id');
if (progress instanceof HTMLProgressElement)
    progress.max = 9;
  

Одна небольшая проблема, связанная с вышесказанным, заключается в том, что если #id не является прогрессом, он будет продолжаться молча. Итак, другой вариант — создать исключение, это также действует как защита типа, но позволяет вам выдавать сообщения о логических ошибках, когда что-то не так.

например..

 const progress = document.querySelector('#id');
if (!(progress instanceof HTMLProgressElement))
  throw new Error('#id not a progress');
progress.max = 9;
  

Комментарии:

1. неплохо. Не знал об этой функции!