-
Notifications
You must be signed in to change notification settings - Fork 12.9k
Closed
Labels
CommittedThe team has roadmapped this issueThe team has roadmapped this issueFixedA PR has been merged for this issueA PR has been merged for this issueSuggestionAn idea for TypeScriptAn idea for TypeScript
Milestone
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>;`
ChiriVulpes, felixfbecker, chuan6, winterbe, emmanueltouzery and 21 more
Metadata
Metadata
Assignees
Labels
CommittedThe team has roadmapped this issueThe team has roadmapped this issueFixedA PR has been merged for this issueA PR has been merged for this issueSuggestionAn idea for TypeScriptAn idea for TypeScript