-
Notifications
You must be signed in to change notification settings - Fork 12.8k
2339 Property 'style' does not exist on type 'Element'. #3263
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
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. class Test {
constructor(elem:HTMLElement) {
elem.style.color = 'red';
};
}
let elem = <HTMLElement>document.querySelector('#test');
let test = new Test(elem); |
@mhegazy yes, I now how to work around it right now, I was just confused what |
According to the MDN spec, |
I am not saying MDN is wrong, I am pretty sure they are right, but they also say what
Same for I do not think svg or xml elements are more frequint for |
DOM Level 3 IDL for Element does not contain it. |
@kitsonk yes, I got it. Please treat now this issue as "Return |
@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. |
As I suggested in issue 424, querySelector/querySelectorAll etc. can return 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
|
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. |
Use a type guard. You need to check for let elem = querySelector("#test")
if (elem instanceof HTMLElement) {
// elem.style
} else {
throw new Error("element #test not in document")
} |
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 |
If someone are still looking for the solution, I can suggest do the following simple solution. Becasue
Hope this help :) |
@quangpdt How it's possible? When I do this: |
I needed only the first element so i used |
when 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 Use type assertion:
I don't think that comment can change type. @devcer querySelector returns one element, not array https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelector |
@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 |
@Dok11 you can add that property to existing interface, i.e. just remove |
@NekR how will I change existing interface? You talk about file |
Sample in whatever place: interface SVGElement {
getTotalLength(): number;
} |
Some example of code:
This produces:
2339 Property 'style' does not exist on type 'Element'.
If I change
elem:Element
toelem: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 whyElement
does not have style property?The text was updated successfully, but these errors were encountered: