TypeScript: 2339 Property 'style' does not exist on type 'Element'.
Some example of code:
class Test {
constructor(elem:Element) {
elem.style.color = 'red';
};
}
let elem = document.querySelector('#test');
let test = new Test(elem);
This produces:
2339 Property 'style' does not exist on type 'Element'.
If I change elem:Element
to elem:HTMLElement
then is says:
2345 Argument of type 'Element' is not assignable to parameter of type 'HTMLElement'. Property 'accessKey' is missing in type 'Element'.
I understand what querySelector
might not always return HTML or SVG elements, but why Element
does not have style property?
About this issue
- Original URL
- State: closed
- Created 9 years ago
- Comments: 23 (6 by maintainers)
I am not the best one to answer the question about the DOM sepec. We do generate these from IE’s definitions. it is possible that it is an issue. @zhengbli would be able to comment better here.
For your issue, i believe you need to use HTMLElement all the time; so assuming you do not use any SVG elements in this code path, casting should be safe.
If someone are still looking for the solution, I can suggest do the following simple solution. Becasue
HTMLElement
was extended fromElement
, so if we queried from the DOM, it’s absolutely aHTMLElement
, we can cast fromElement
toHTMLElement
by using:Hope this help 😃
SVG elements DO have ‘style’ property in browsers (including MS IE11 and Edge), so usually you don’t have to check for its existence.
The exception is arbitrary XML elements, including MathML in Firefox ( Safari not tested ). MathML is dying and most web developers don’t mix arbitrary XML in HTML, so this is not a problem in practice.
According to the CSSOM spec, both
HTMLElement
andSVGElement
havestyle
propterty (Element
doesn’t, however). So I suggest addingstyle
toSVGElement
, and toElement
as an optional property in TS. can we reopen this issue?Use a type guard. You need to check for
null
anyway.SVG elements really do exist.
If your JS runs over arbitrary DOM trees, it might encounter one, and we’d be wrong to act as if that were not the case.
@NekR while i agree that an HTMLElement is more common target for querySelector/querySelectorAll, this change leaves users of SVGElements with one extra cast:
That is a breaking change though, as it will break existing calls that expect to cast to SVGElement.
I am not saying MDN is wrong, I am pretty sure they are right, but they also say what
Element
haveElement.onwheel
😃Same for
getElementById
, it does not returnsHTMLElement
more often than, for example,querySelector
because one can easily request inline SVG element by id.I do not think svg or xml elements are more frequint for
querySelector
, but I can agree what for XPath that might not be true. So, sincequerySelector
returnsElement
then any developer should cast it to type they wanted (HTML, SVG, something else?). It would be good to haveHTMLElement
as a default for such methods, since (as far as I know 😃) HTML is default for the web (ignore xhtml here).