Skip to content

Commit

Permalink
correct implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
michaelficarra committed Dec 3, 2024
1 parent 2f213af commit 8104939
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 30 deletions.
9 changes: 5 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,6 @@
"devDependencies": {
"@tc39/ecma262-biblio": "2.1.2775",
"ecmarkup": "20.0.0",
"typescript": "5.2.2"
"typescript": "5.7.2"
}
}
74 changes: 50 additions & 24 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,30 +1,56 @@
declare var Iterator: {};

if (typeof Iterator === 'undefined' || Iterator == null) {
globalThis.Iterator = function() {};
}

function concatImpl<A>(...iterables: Array<Iterable<A>>): Generator<A>
function concatImpl(): Generator<never>
function concatImpl<A>(iterableA: Iterable<A>): Generator<A>
function concatImpl<A, B>(iterableA: Iterable<A>, iterableB: Iterable<B>): Generator<A | B>
function concatImpl<A, B, C>(iterableA: Iterable<A>, iterableB: Iterable<B>, iterableC: Iterable<C>): Generator<A | B | C>
function concatImpl<A, B, C, D>(iterableA: Iterable<A>, iterableB: Iterable<B>, iterableC: Iterable<C>, iterableD: Iterable<D>): Generator<A | B | C | D>
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>
function concatImpl(...iterables: Array<Iterable<unknown>>): Generator<unknown>
function concatImpl(...iterables: Array<unknown>): Generator<unknown> {
const openMethods = [];
for (let iterable of iterables) {
if (iterable == null || Object(iterable) !== iterable) throw new TypeError;
let openMethod = (iterable as any)[Symbol.iterator];
function concatImpl(): Iterator<never>
function concatImpl<A>(...iterables: Array<Iterable<A>>): Iterator<A>
function concatImpl<A>(iterableA: Iterable<A>): Iterator<A>
function concatImpl<A, B>(iterableA: Iterable<A>, iterableB: Iterable<B>): Iterator<A | B>
function concatImpl<A, B, C>(iterableA: Iterable<A>, iterableB: Iterable<B>, iterableC: Iterable<C>): Iterator<A | B | C>
function concatImpl<A, B, C, D>(iterableA: Iterable<A>, iterableB: Iterable<B>, iterableC: Iterable<C>, iterableD: Iterable<D>): Iterator<A | B | C | D>
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>
function concatImpl(...iterables: Array<Iterable<unknown>>): Iterator<unknown>
function concatImpl(...iterables: Array<unknown>): Iterator<unknown> {
const openMethods: Array<{ openMethod: () => Iterator<unknown>, iterable: Iterable<unknown>}> = [];
for (let val of iterables) {
if (val == null || Object(val) !== val) throw new TypeError;
let iterable: Iterable<unknown> = val as Iterable<unknown>;
let openMethod = iterable[Symbol.iterator];
if (typeof openMethod !== 'function') throw new TypeError;
openMethods.push({openMethod, iterable});
}
return function*() {
for (let { openMethod, iterable } of openMethods) {
yield* { [Symbol.iterator]() { return openMethod.call(iterable); } }
}
}();
let done = false;
let iterator: Iterator<unknown> | null = null;
let nextMethod: Iterator<unknown>["next"] | null = null;
return Iterator.from({
next() {
while (!done) {
if (iterator != null && nextMethod != null) {
let iterResult = nextMethod.call(iterator);
if (!iterResult.done) {
return iterResult;
}
iterator = null;
nextMethod = null;
}
if (openMethods.length > 0) {
let { openMethod, iterable } = openMethods.shift()!;
let val = openMethod.call(iterable);
if (val == null || Object(val) !== val) throw new TypeError;
iterator = val as Iterator<unknown>;
nextMethod = iterator.next;
continue;
}
done = true;
}
return { done: true, value: void 0 };
},
return() {
if (!done) {
if (iterator != null) {
iterator.return?.().value;
}
done = true;
}
return { done: true, value: void 0, };
},
});
}

// NOTE: this line makes concat non-constructible, and gives it the appropriate name and length
Expand Down
2 changes: 1 addition & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
// "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */

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

0 comments on commit 8104939

Please sign in to comment.