Why forEach does not exist on NodeListOf

Viewed 19697

My code:

    var checkboxes = this.element.querySelectorAll("input[type=checkbox]") as NodeListOf<HTMLInputElement>;
    checkboxes.forEach(ele => {
        var key = ele.name;
        if (data.hasOwnProperty(key)) {
            if (!this.isArray(data[key])) {
                var temp = data[key];
                data[key] = [temp];
            }
        } else {
            data[key] = [];
        }
    });

But I got an error:

error TS2339: Property 'forEach' does not exist on type 'NodeListOf'.

interface NodeListOf<TNode extends Node> extends NodeList {
    length: number;
    item(index: number): TNode;
    [index: number]: TNode;
}

interface NodeList {
    /**
     * Returns an array of key, value pairs for every entry in the list
     */
    entries(): IterableIterator<[number, Node]>;
    /**
     * Performs the specified action for each node in an list.
     * @param callbackfn  A function that accepts up to three arguments. forEach calls the callbackfn function one time for each element in the list.
     * @param thisArg  An object to which the this keyword can refer in the callbackfn function. If thisArg is omitted, undefined is used as the this value.
     */
    forEach(callbackfn: (value: Node, index: number, listObj: NodeList) => void, thisArg?: any): void;
    /**
     * Returns an list of keys in the list
     */
    keys(): IterableIterator<number>;

    /**
     * Returns an list of values in the list
     */
    values(): IterableIterator<Node>;


    [Symbol.iterator](): IterableIterator<Node>;
}

'NodeListOf' inherit from 'NodeList',and 'NodeList' has 'forEach' method,why 'forEach' does not exist on 'NodeListOf'?

2 Answers

There is no guarantee forEach will exist on this type - it can, but not necessarily (e.g. in PhantomJS and IE), so TypeScript disallows it by default. In order to iterate over it you can use:

1) Array.from():

Array.from(checkboxes).forEach((el) => { /* do something */});

2) for-in:

for (let i in checkboxes) {
  if (checkboxes.hasOwnProperty(i)) {
    console.log(checkboxes[i]);
  }
}
Related