Skip to content

Commit 8104939

Browse files
correct implementation
1 parent 2f213af commit 8104939

File tree

4 files changed

+57
-30
lines changed

4 files changed

+57
-30
lines changed

package-lock.json

Lines changed: 5 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,6 @@
2121
"devDependencies": {
2222
"@tc39/ecma262-biblio": "2.1.2775",
2323
"ecmarkup": "20.0.0",
24-
"typescript": "5.2.2"
24+
"typescript": "5.7.2"
2525
}
2626
}

src/index.ts

Lines changed: 50 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,56 @@
1-
declare var Iterator: {};
2-
3-
if (typeof Iterator === 'undefined' || Iterator == null) {
4-
globalThis.Iterator = function() {};
5-
}
6-
7-
function concatImpl<A>(...iterables: Array<Iterable<A>>): Generator<A>
8-
function concatImpl(): Generator<never>
9-
function concatImpl<A>(iterableA: Iterable<A>): Generator<A>
10-
function concatImpl<A, B>(iterableA: Iterable<A>, iterableB: Iterable<B>): Generator<A | B>
11-
function concatImpl<A, B, C>(iterableA: Iterable<A>, iterableB: Iterable<B>, iterableC: Iterable<C>): Generator<A | B | C>
12-
function concatImpl<A, B, C, D>(iterableA: Iterable<A>, iterableB: Iterable<B>, iterableC: Iterable<C>, iterableD: Iterable<D>): Generator<A | B | C | D>
13-
function concatImpl<A, B, C, D, E>(iterableA: Iterable<A>, iterableB: Iterable<B>, iterableC: Iterable<C>, iterableD: Iterable<D>, iterableE: Iterable<E>): Generator<A | B | C | D | E>
14-
function concatImpl(...iterables: Array<Iterable<unknown>>): Generator<unknown>
15-
function concatImpl(...iterables: Array<unknown>): Generator<unknown> {
16-
const openMethods = [];
17-
for (let iterable of iterables) {
18-
if (iterable == null || Object(iterable) !== iterable) throw new TypeError;
19-
let openMethod = (iterable as any)[Symbol.iterator];
1+
function concatImpl(): Iterator<never>
2+
function concatImpl<A>(...iterables: Array<Iterable<A>>): Iterator<A>
3+
function concatImpl<A>(iterableA: Iterable<A>): Iterator<A>
4+
function concatImpl<A, B>(iterableA: Iterable<A>, iterableB: Iterable<B>): Iterator<A | B>
5+
function concatImpl<A, B, C>(iterableA: Iterable<A>, iterableB: Iterable<B>, iterableC: Iterable<C>): Iterator<A | B | C>
6+
function concatImpl<A, B, C, D>(iterableA: Iterable<A>, iterableB: Iterable<B>, iterableC: Iterable<C>, iterableD: Iterable<D>): Iterator<A | B | C | D>
7+
function concatImpl<A, B, C, D, E>(iterableA: Iterable<A>, iterableB: Iterable<B>, iterableC: Iterable<C>, iterableD: Iterable<D>, iterableE: Iterable<E>): Iterator<A | B | C | D | E>
8+
function concatImpl(...iterables: Array<Iterable<unknown>>): Iterator<unknown>
9+
function concatImpl(...iterables: Array<unknown>): Iterator<unknown> {
10+
const openMethods: Array<{ openMethod: () => Iterator<unknown>, iterable: Iterable<unknown>}> = [];
11+
for (let val of iterables) {
12+
if (val == null || Object(val) !== val) throw new TypeError;
13+
let iterable: Iterable<unknown> = val as Iterable<unknown>;
14+
let openMethod = iterable[Symbol.iterator];
2015
if (typeof openMethod !== 'function') throw new TypeError;
2116
openMethods.push({openMethod, iterable});
2217
}
23-
return function*() {
24-
for (let { openMethod, iterable } of openMethods) {
25-
yield* { [Symbol.iterator]() { return openMethod.call(iterable); } }
26-
}
27-
}();
18+
let done = false;
19+
let iterator: Iterator<unknown> | null = null;
20+
let nextMethod: Iterator<unknown>["next"] | null = null;
21+
return Iterator.from({
22+
next() {
23+
while (!done) {
24+
if (iterator != null && nextMethod != null) {
25+
let iterResult = nextMethod.call(iterator);
26+
if (!iterResult.done) {
27+
return iterResult;
28+
}
29+
iterator = null;
30+
nextMethod = null;
31+
}
32+
if (openMethods.length > 0) {
33+
let { openMethod, iterable } = openMethods.shift()!;
34+
let val = openMethod.call(iterable);
35+
if (val == null || Object(val) !== val) throw new TypeError;
36+
iterator = val as Iterator<unknown>;
37+
nextMethod = iterator.next;
38+
continue;
39+
}
40+
done = true;
41+
}
42+
return { done: true, value: void 0 };
43+
},
44+
return() {
45+
if (!done) {
46+
if (iterator != null) {
47+
iterator.return?.().value;
48+
}
49+
done = true;
50+
}
51+
return { done: true, value: void 0, };
52+
},
53+
});
2854
}
2955

3056
// NOTE: this line makes concat non-constructible, and gives it the appropriate name and length

tsconfig.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
// "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */
1212

1313
/* Language and Environment */
14-
"target": "es2022", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */
14+
"target": "esnext", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */
1515
// "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */
1616
// "jsx": "preserve", /* Specify what JSX code is generated. */
1717
// "experimentalDecorators": true, /* Enable experimental support for legacy experimental decorators. */

0 commit comments

Comments
 (0)