How to assert a type of an HTMLElement in TypeScript?
I'm trying to do this:
var script:HTMLScriptElement = document.getElementsByName("script")[0];
alert(script.type);
but it's giving me an error:
Cannot convert 'Node' to 'HTMLScriptElement': Type 'Node' is missing property 'defer' from type 'HTMLScriptElement'
(elementName: string) => NodeList
I can't access the 'type' member of the script element unless I cast it to the correct type, but I don't know how to do this. I searched the docs & samples, but I couldn't find anything.
Solution 1:
TypeScript uses '<>' to surround casts, so the above becomes:
var script = <HTMLScriptElement>document.getElementsByName("script")[0];
However, unfortunately you cannot do:
var script = (<HTMLScriptElement[]>document.getElementsByName(id))[0];
You get the error
Cannot convert 'NodeList' to 'HTMLScriptElement[]'
But you can do :
(<HTMLScriptElement[]><any>document.getElementsByName(id))[0];
Solution 2:
As of TypeScript 0.9 the lib.d.ts
file uses specialized overload signatures that return the correct types for calls to getElementsByTagName
.
This means you no longer need to use type assertions to change the type:
// No type assertions needed
var script: HTMLScriptElement = document.getElementsByTagName('script')[0];
alert(script.type);
Solution 3:
Do not type cast. Never. Use type guards:
const e = document.getElementsByName("script")[0];
if (!(e instanceof HTMLScriptElement))
throw new Error(`Expected e to be an HTMLScriptElement, was ${e && e.constructor && e.constructor.name || e}`);
// locally TypeScript now types e as an HTMLScriptElement, same as if you casted it.
Let the compiler do the work for you and get errors when your assumptions turn out wrong.
It may look overkill in this case, but it will help you a lot if you come back later and change the selector, like adding a class that is missing in the dom, for example.