Closed
Description
TypeScript Version: 2.0.3
The definition in lib.es6.d.ts
of IteratorResult
(removing the ?
after value
) seems to have broken existing Iterator implementations, and is particularly troublesome with strict null checking enabled. See http://stackoverflow.com/questions/39813087/why-did-typescript-2-0-change-iteratorresultk for more details.
Code
A short version:
export interface JavaIterator<E> {
hasNext(): boolean;
next(): E;
remove(): void;
}
...
class IterableAdapter<T> implements Iterable<T>, IterableIterator<T> {
private _iterator: JavaIterator<T>
constructor(private collection: JavaCollection<T>){}
[Symbol.iterator]() { this._iterator = this.collection.iterator(); return this;}
next(): IteratorResult<T> {
if (!this._iterator.hasNext()) return { done: true }; // Error on this line
return {done: false, value: this._iterator.next()}
}
}
this version works
class IterableAdapter<T> implements Iterable<T>, IterableIterator<T> {
private _iterator: JavaIterator<T>
constructor(private collection: JavaCollection<T>){}
[Symbol.iterator]() { this._iterator = this.collection.iterator(); return this;}
next(): IteratorResult<T> {
if (!this._iterator.hasNext()) {
// A bit of a hack needed here needed for strict null checking
return { done: true, value: undefined } as any as IteratorResult<T>;
}
return {done: false, value: this._iterator.next()}
}
}
original bug
class HashMapKeyIterable<K,V> implements Iterator<K>, IterableIterator<K> {
private _bucket: HashMapEntry<K,V>[];
private _index: number;
constructor( private _buckets : Iterator<HashMapEntry<K,V>[]> ){
this._bucket = undefined;
this._index = undefined;
}
[Symbol.iterator]() { return this }
next(): IteratorResult<K> {
while (true) {
if (this._bucket) {
const i = this._index++;
if (i < this._bucket.length) {
let item = this._bucket[i];
return {done: false, value: item.key}
}
}
this._index = 0
let x = this._buckets.next();
if (x.done) return {done: true}; // Under TS 2.0 this needs to
this._bucket = x.value; // return {done: true: value: undefined};
}
}
}
Expected behavior:
Clean compile under TypeScript 2.0
Actual behavior:
Errors reported: TS2322: Type '{ done: true; }' is not assignable to type 'IteratorResult'. Property 'value' is missing in type '{ done: true; }'
Note: with strict null checking on, I seem to need to go further, resorting to
return { done: true, value: undefined } as any as IteratorResult<T>;`