Search code examples
typescriptangularwebstorm

Error assigning variable type


I'm afraid I'm not sure if this is a question about WebStorm, Angular2 or Typescript.

I have an Angular2 build set up and am using WebStorm 2016.1.2 to edit with. One of my components gets a reference to a DOM element using a simple document.getElementById('some-el'); and passes this to a service method:

calc(el:HTMLElement){
    this.height = el.offsetHeight;
    this.width = el.offsetWidth;

    let span:HTMLElement = el.querySelector("span");
    this.pos = span.offsetTop - span.offsetHeight;
}

Everything works fine and I don't get any errors in the browser but I do get an error in WebStorm linked to el.querySelector("span");

The error says: Initializer type Element is not assignable to variable type HTMLElement

I don't know if this a problem with WebStorm or if I am actually typing things wrong. If I set the type of span to Element the error disappears but then the offsetTop and offsetHeight are highlighted as incorrect??

As the actual build doesn't seem to suffer when I run it I just wonder if this is something in my code I need to fix or something in my editor that I can ignore?

Cheers for your help


Solution

  • You just need to cast it:

    calc(el:HTMLElement){
        this.height = el.offsetHeight;
        this.width = el.offsetWidth;
    
        let span:HTMLElement = <HTMLElement> el.querySelector("span");
        this.pos = span.offsetTop - span.offsetHeight;
    }
    

    Or you can use type assertion:

    let span:HTMLElement = el.querySelector("span") as HTMLElement;
    

    What happens is that querySelector returns Element and not HTMLElement as you declared the type of span to be. But you can tell the compiler to "trust you" that you know that it's indeed an HTMLElement.

    You can also use HTMLSpanElement instead of the HTMLElement which is more specific, just like HTMLElement is more specific than Element (that's why when you changed it to Element the offsetTop and offsetHeight weren't available).