TypeScript: implementation of [Symbol.iterator]: why it doesn't work on unit test (Karma + Jasmine?

Viewed 5688

My interface defines the iterator:

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

My class DocumentManager implements this interface:

*[Symbol.iterator](): IterableIterator<IDocument>{
    for(let n of this._documents){// this._documents is Array<IDocument>
        yield n;
    }
}

In debug mode I see this._documents has three documents, but this code doesn't iteration:

let m = 0;
for(let n of app.documentManager){
    ++m;
}
// here m == 0 still...

So the iteration doesn't happen. What I did wrong?

UPD

For example, it works in JavaScript:

let collection = {
    items : ['a','b','c','d','e'],
    *[Symbol.iterator](){
        for(let item of this.items){
            yield item;
        }
    }
};

for(let n of collection){
    console.log(n);
}

Why I have the problem with TypeScript?

UPD2

Oh, now I see it doesn't work only on the unit test (Karma + Jasmine) but works fine in Node.js. But I need my unit tests work too.... :(((

1 Answers

I'm not sure what you did wrong, but here is some typescript code that compiles and runs fine:

interface IterateNum {
  [Symbol.iterator](): IterableIterator<number>;
}

class Collection implements IterateNum {
    private items = [1,2,3,4]; // can be Array<T>

    constructor() {}

    *[Symbol.iterator]() {
        for(let i of this.items) {
            yield i;
        }
    }
}

for(let n of (new Collection())) {
    console.log(n);
}

I wrote the above code, and copied your tsconfig.json and running tsc and node dist/file.js works fine. Something else is likely wrong with your code. Try writing a minimal, standalone script to get the pieces you are interested in working together, and isolate call sites.


Notes about this feature set in general:

You need to implement the interface (the next function), not just yield values. This online gitbook does a good job on how to implement an interator in TS.

Here's a related PR that describes more details of the TS implementation.

There's some wonkiness with the for-of down-level emitting, so make sure your tsconfig is set up properly. (target es6, as per this issue)

Note - worth mentioning this other SO answer, the question is slightly different, but the linked answer talks explicitly about an Iterable version that looks more like what this OP is looking for.

Related