Repository navigation
2339 Property 'style' does not exist on type 'Element'. #3263
Description
Activity
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. Zhengbo Li (@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.
class Test { constructor(elem:HTMLElement) { elem.style.color = 'red'; }; } let elem = <HTMLElement>document.querySelector('#test'); let test = new Test(elem);
Reacted by Harry Jubb, Tomas Sandven, Alexander Kozhevin, carrot, Gerard Rovira, adwilliamjr, Sergey Sagan, abbymrs, Jimi, Claudio Holanda Jr. and 18 more- addedQuestionAn issue which isn't directly actionable in codeAn issue which isn't directly actionable in code
on May 25, 2015 Mohamed Hegazy (@mhegazy) yes, I now how to work around it right now, I was just confused what
Elementdoes not havestyleproperty. I am also not sure if it should have it, but it will be strange in a future to always cast any DOM requests (querySelector,getElementById, etc) toHTMLElement.According to the MDN spec,
Elementinterface doesn't have astyleproperty, andquerySelectordoes returnElement.
However, in the case ofgetElementById, we made it convenient by returningHTMLElementby default, although it is different from the spec. I don't know if we should do the same thing for other methods that don't obviously returnHTMLElementoverElementin most of the time, as it does feel hacky and inconsistent.I am not saying MDN is wrong, I am pretty sure they are right, but they also say what
ElementhaveElement.onwheel:-)that don't obviously return HTMLElement over Element in most of the time, as it does feel hacky and inconsistent.
Same for
getElementById, it does not returnsHTMLElementmore often than, for example,querySelectorbecause 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, sincequerySelectorreturnsElementthen any developer should cast it to type they wanted (HTML, SVG, something else?). It would be good to haveHTMLElementas a default for such methods, since (as far as I know :-)) HTML is default for the web (ignore xhtml here).Reacted by Tony BabenkoDOM Level 3 IDL for Element does not contain it.
Kitson Kelly (@kitsonk) yes, I got it. Please treat now this issue as "Return
HTMLElementby default instead ofElementfrom dom request methods (getElement(s)By*,querySelector(All), etc)"Arthur Stolyar (@NekR) while i agree that an HTMLElement is more common target for querySelector/querySelectorAll, this change leaves users of SVGElements with one extra cast:
// with the current definition querySelector(selectors: string): Element; // this is how you access it let htmlElement = <HTMLElement>document.querySelector('#test'); let svgElement = <SVGElement>document.querySelector('#test'); // if it was changes to HTMLElement querySelector(selectors: string): HTMLElement; // this is how you access it let htmlElement = document.querySelector('#test'); let svgElement = <SVGElement><Element>document.querySelector('#test');
That is a breaking change though, as it will break existing calls that expect to cast to SVGElement.
Reacted by Tu ChuAs I suggested in issue 424, querySelector/querySelectorAll etc. can return
UniversalElementby default, which is an imaginary Element that extends all known sub-interfaces of Element. Thus no casts are ever needed, no matter for HTML or SVG.Of cause this is not quite conformant to WebIDL of DOM specs, but I don't think there are many TS users that care about this problem.
Indeed, double casting seems weird. But it's also strange that TypeScript follows spec more than real use cases. What is a real benefit of returning
Elementfor such methods except of being type-compatible with spec?UniversalElementsolution seems good. I do not know if it's possible, but something like that will help.RyanCavanaugh commented
on May 28, 2015 MemberMore actionsSVG 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.
Reacted by Jamie Birch, Matthew Downs and Vincent CantinUse a type guard. You need to check for
nullanyway.let elem = querySelector("#test") if (elem instanceof HTMLElement) { // elem.style } else { throw new Error("element #test not in document") }
Reacted by everdimension, The web walker, Takashi Yamamiya, Ali and Mauro Reis VieiraSVG 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
HTMLElementandSVGElementhavestylepropterty (Elementdoesn't, however). So I suggest addingstyletoSVGElement, and toElementas an optional property in TS. can we reopen this issue?Reacted by Jamie Birch, JamesYin, Daniel, Roland Kontson, Tomas Sandven, will, Lazar Ljubenović, Matthew Downs, xtianus79 and VytenisIf someone are still looking for the solution, I can suggest do the following simple solution. Becasue
HTMLElementwas extended fromElement, so if we queried from the DOM, it's absolutely aHTMLElement, we can cast fromElementtoHTMLElementby using:(document.querySelector('ion-nav') as HTMLElement).style.color = 'red';Hope this help :)
Reacted by Anton Yushkevich, Rep1ay, Artem Belik, grzeslaws, Alexis374, Reza and Luciano BecerraReacted by Maxime Lafarie, Cameron Moss, Chen Asraf, Anton Yushkevich, Armen , Reza and Luciano BecerraQuang Pham (@quangpdt)
I have a bug:
Type 'Element' is not assignable to type 'HTMLElement'.Property 'accessKey' is missing in type 'Element'.
In:
/** @type {HTMLElement} */ const enSentenceEl = /** @type {HTMLElement} */ sentenceEl.querySelector(".enSentence");How it's possible?
After all, HTMLElement inherits from Element.When I do this:
const enSentenceEl = /** @type {HTMLElement} */ sentenceEl.querySelector(".enSentence");
Element type simply does not change. Still only: Element.aluanhaddad commented
on Oct 2, 2017 ContributorMore actionswhen you know I specific ID in your HTML corresponds to a more specialized type than that returned by the DOM APIs I find the following pattern to be very useful and that it satisfies the typechecker while making the code more self documenting
declare global { interface Document { querySelector(s: '#test'): NodeList<Element & Extras>; } }
look997 (@look997) Use type assertion:
as HTMLElement
I don't think that comment can change type.
Santosh Viswanatham (@devcer) querySelector returns one element, not array https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelector
look997 (@look997) Use type assertion:
W pliku JavaScript? Tam chyba się nie da tak?
Ja to mam w pliku js.look997 (@look997) A to nie wiem, nigdy typescriptu nie używałem w pliku js. Może po prostu przejdź na używanie plików .ts. https://www.typescriptlang.org/docs/handbook/migrating-from-javascript.html
Oleg Postoev (@Dok11) you can add that property to existing interface, i.e. just remove
SVGElementEx extends.Arthur Stolyar (@NekR) how will I change existing interface? You talk about file
\lib.es6.d.ts?
Can you show simple example?Sample in whatever place:
interface SVGElement { getTotalLength(): number; }
- locked and limited conversation to collaborators
on Jun 19, 2018

Some example of code:
This produces:
2339 Property 'style' does not exist on type 'Element'.If I change
elem:Elementtoelem:HTMLElementthen 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
querySelectormight not always return HTML or SVG elements, but whyElementdoes not have style property?