TypeScript: casting HTMLElement

后端 未结 13 2103
我寻月下人不归
我寻月下人不归 2020-12-02 05:34

Does anyone know how to cast in TypeScript?

I\'m trying to do this:

var script:HTMLScriptElement = document.getElementsByName(\"script\")[0];
alert(s         


        
相关标签:
13条回答
  • 2020-12-02 05:44

    To end up with:

    • an actual Array object (not a NodeList dressed up as an Array)
    • a list that is guaranteed to only include HTMLElements, not Nodes force-casted to HTMLElements
    • a warm fuzzy feeling to do The Right Thing

    Try this:

    let nodeList : NodeList = document.getElementsByTagName('script');
    let elementList : Array<HTMLElement> = [];
    
    if (nodeList) {
        for (let i = 0; i < nodeList.length; i++) {
            let node : Node = nodeList[i];
    
            // Make sure it's really an Element
            if (node.nodeType == Node.ELEMENT_NODE) {
                elementList.push(node as HTMLElement);
            }
        }
    }
    

    Enjoy.

    0 讨论(0)
  • 2020-12-02 05:44

    Since it's a NodeList, not an Array, you shouldn't really be using brackets or casting to Array. The property way to get the first node is:

    document.getElementsByName(id).item(0)
    

    You can just cast that:

    var script = <HTMLScriptElement> document.getElementsByName(id).item(0)
    

    Or, extend NodeList:

    interface HTMLScriptElementNodeList extends NodeList
    {
        item(index: number): HTMLScriptElement;
    }
    var scripts = <HTMLScriptElementNodeList> document.getElementsByName('script'),
        script = scripts.item(0);
    
    0 讨论(0)
  • 2020-12-02 05:46

    Just to clarify, this is correct.

    Cannot convert 'NodeList' to 'HTMLScriptElement[]'

    as a NodeList is not an actual array (e.g. it doesn't contain .forEach, .slice, .push, etc...).

    Thus if it did convert to HTMLScriptElement[] in the type system, you'd get no type errors if you tried to call Array.prototype members on it at compile time, but it would fail at run time.

    0 讨论(0)
  • 2020-12-02 05:50

    This seems to solve the problem, using the [index: TYPE] array access type, cheers.

    interface ScriptNodeList extends NodeList {
        [index: number]: HTMLScriptElement;
    }
    
    var script = ( <ScriptNodeList>document.getElementsByName('foo') )[0];
    
    0 讨论(0)
  • 2020-12-02 05:50

    Could be solved in the declaration file (lib.d.ts) if TypeScript would define HTMLCollection instead of NodeList as a return type.

    DOM4 also specifies this as the correct return type, but older DOM specifications are less clear.

    See also http://typescript.codeplex.com/workitem/252

    0 讨论(0)
  • 2020-12-02 05:55

    You always can hack type system using:

    var script = (<HTMLScriptElement[]><any>document.getElementsByName(id))[0];
    
    0 讨论(0)
提交回复
热议问题