2

Let's say i have a HTML element as following:

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

VSCode shows a problem ('Property "max" does not exist on type "Element"'), if i select this element like this:

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

There will be no problems, if i select via element selector:

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

Can i do something like type assertion to avoid this kind of behavior or what are good practises to handle this problem in regular javascript?

4
  • 1
    queryselector can return any type of element of you provide an id, or class etc. So you will need to cast manually.. Commented Oct 1, 2020 at 8:46
  • 1
    have you tried getElementById Commented Oct 1, 2020 at 8:48
  • 1
    Typescript cannot check your HTML. It can only deduce that if the selector is progress then the result is HTMLProgressElement | null. This will work for every other element too. div => HTMLDivElement, input => HTMLInputElement, etc... But if you add any other selector to it, it cannot do it. Commented Oct 1, 2020 at 9:21
  • What's a bit odd is, that even input#id doesn't tell TS, that the selected element is a HTMLProgessElement as far as i tested. Commented Oct 1, 2020 at 11:18

1 Answer 1

4

Personally I would just move to TS, but even then you would still need to cast. To cast the type in JS you can do ->

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

In Typescript it would have been like ->

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

Another nice feature, you can create type guards, and this also helps the compiler.

eg, this below will work in both TS & JS.

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

One slight issue with the above, is if #id is not a Progress it will silently continue. So another option is to throw an exception, this also acts as a type guard, but allows you to throw logical error messages when things are not right.

eg..

const progress = document.querySelector('#id');
if (!(progress instanceof HTMLProgressElement))
  throw new Error('#id not a progress');
progress.max = 9;
Sign up to request clarification or add additional context in comments.

1 Comment

nice. Didn't know about this feature!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.