cdecompilador
cdecompilador

Reputation: 113

Casting works but declaring type doesn't autocast variables

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

Answers (2)

Thomas Renger
Thomas Renger

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

BoyFarmer
BoyFarmer

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;

details here

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

Related Questions