Reputation: 113
I'm new to typescript and while I was making a canvas game for fun I encountered just at the begining a weird thing.
// 1) Works but stores HTMLElement, so later fails
const canvas = document.getElementById("game");
// 2) Don't works
const canvas: HTMLCanvasElement = document.getElementById("game");
// 3) Works
const canvas = document.getElementById("game") as HTMLCanvasElement;
// 4) Works
const canvas: HTMLCanvasElement = document.getElementById("game") as HTMLCanvasElement;
The awnser is why the second one doesn't work, shouldn't it try to autocast to the declared type? I think the last two ones are too verbose or not very clear. I'd like to know if there is a compiler option or if this is just happening to me. Thanks in advance.
Upvotes: 0
Views: 63
Reputation: 1044
Well, document.getElementById
returns HtmlElement or null. It is not a generic method which is able to return HtmlCanvasElement.
So the type of first line should be HtmlElement | null.
As HtmlCanvasElement extends HtmlElement and not the other way around. The second line is not working.
Line 3 & 4 is the same but contain potential risk because, the ide does not help to should you a variable could be null => runtime error. and sure if you would call something only defined on HtmlCanvasElement but the id would not a HtmlCanvasElement you would see a runtime error again.
And at the end you should know typescript & types are only at development time. It helps you developing stuff. At the end it is javascript in you browser having know idea about types javascript cannot understand.
Upvotes: 1
Reputation: 101
It is because compiler doesn't know type of your html tag with id=game
in runtime.
getElementById signature looks like:
getElementById(elementId: string): HTMLElement | null;
and in typescript HTMLElement | null
is not assignable to HTMLCanvasElement
, because HTMLCanvasElement
is just one of subtypes (and it can be null to)
If you are sure, that you tag always is of type HTMLCanvasElement
you can tell to compiler
Hey man! I know that this function always return
HTMLCanvasElement
in runtime. Trust me!
And you can use one of your working examples with as
keyword
Upvotes: 1