#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, что выбранный элемент является aHTMLProgessElement
, насколько я тестировал.
Ответ №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. неплохо. Не знал об этой функции!