diff --git a/src/lib/esnext.iterator.d.ts b/src/lib/esnext.iterator.d.ts index fe929f59c2206..994cde1639216 100644 --- a/src/lib/esnext.iterator.d.ts +++ b/src/lib/esnext.iterator.d.ts @@ -7,12 +7,12 @@ export {}; // Abstract type that allows us to mark `next` as `abstract` -declare abstract class Iterator { // eslint-disable-line @typescript-eslint/no-unsafe-declaration-merging - abstract next(value?: TNext): IteratorResult; +declare abstract class Iterator { // eslint-disable-line @typescript-eslint/no-unsafe-declaration-merging + abstract next(value?: TNext): IteratorResult; } // Merge all members of `IteratorObject` into `Iterator` -interface Iterator extends globalThis.IteratorObject {} +interface Iterator extends globalThis.IteratorObject {} // Capture the `Iterator` constructor in a type we can use in the `extends` clause of `IteratorConstructor`. type IteratorObjectConstructor = typeof Iterator; @@ -123,7 +123,7 @@ declare global { * Returns its input if the input already inherits from the built-in Iterator class. * @param value An iterator or iterable object to convert a native iterator. */ - from(value: Iterator | Iterable): IteratorObject; + from(value: Iterator | Iterable): IteratorObject; } var Iterator: IteratorConstructor; diff --git a/tests/baselines/reference/awaitUsingDeclarationsWithIteratorObject.types b/tests/baselines/reference/awaitUsingDeclarationsWithIteratorObject.types index 54cd3d16dd0e9..1e07140315252 100644 --- a/tests/baselines/reference/awaitUsingDeclarationsWithIteratorObject.types +++ b/tests/baselines/reference/awaitUsingDeclarationsWithIteratorObject.types @@ -56,12 +56,12 @@ async function f() { > : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ >Iterator.from(i) : IteratorObject > : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ->Iterator.from : (value: Iterator | Iterable) => IteratorObject -> : ^ ^^ ^^ ^^^^^ +>Iterator.from : (value: Iterator | Iterable) => IteratorObject +> : ^ ^^ ^^^^^^^^ ^^ ^^^^^ >Iterator : IteratorConstructor > : ^^^^^^^^^^^^^^^^^^^ ->from : (value: Iterator | Iterable) => IteratorObject -> : ^ ^^ ^^ ^^^^^ +>from : (value: Iterator | Iterable) => IteratorObject +> : ^ ^^ ^^^^^^^^ ^^ ^^^^^ >i : Iterator > : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/baselines/reference/builtinIterator.errors.txt b/tests/baselines/reference/builtinIterator.errors.txt index c4fc043ee366e..f653652343897 100644 --- a/tests/baselines/reference/builtinIterator.errors.txt +++ b/tests/baselines/reference/builtinIterator.errors.txt @@ -20,10 +20,10 @@ builtinIterator.ts(60,3): error TS2416: Property 'next' in type 'BadIterator3' i Type '{ done: boolean; value: number; }' is not assignable to type 'IteratorYieldResult'. Types of property 'done' are incompatible. Type 'boolean' is not assignable to type 'false'. -builtinIterator.ts(70,29): error TS2345: Argument of type 'Generator' is not assignable to parameter of type 'Iterator | Iterable'. - Type 'Generator' is not assignable to type 'Iterator'. +builtinIterator.ts(70,29): error TS2345: Argument of type 'Generator' is not assignable to parameter of type 'Iterator | Iterable'. + Type 'Generator' is not assignable to type 'Iterator'. Types of property 'next' are incompatible. - Type '(...[value]: [] | [boolean]) => IteratorResult' is not assignable to type '(...[value]: [] | [undefined]) => IteratorResult'. + Type '(...[value]: [] | [boolean]) => IteratorResult' is not assignable to type '(...[value]: [] | [undefined]) => IteratorResult'. Types of parameters '__0' and '__0' are incompatible. Type '[] | [undefined]' is not assignable to type '[] | [boolean]'. Type '[undefined]' is not assignable to type '[] | [boolean]'. @@ -139,10 +139,10 @@ builtinIterator.ts(73,35): error TS2322: Type 'Generator; const iter1 = Iterator.from(g1); ~~ -!!! error TS2345: Argument of type 'Generator' is not assignable to parameter of type 'Iterator | Iterable'. -!!! error TS2345: Type 'Generator' is not assignable to type 'Iterator'. +!!! error TS2345: Argument of type 'Generator' is not assignable to parameter of type 'Iterator | Iterable'. +!!! error TS2345: Type 'Generator' is not assignable to type 'Iterator'. !!! error TS2345: Types of property 'next' are incompatible. -!!! error TS2345: Type '(...[value]: [] | [boolean]) => IteratorResult' is not assignable to type '(...[value]: [] | [undefined]) => IteratorResult'. +!!! error TS2345: Type '(...[value]: [] | [boolean]) => IteratorResult' is not assignable to type '(...[value]: [] | [undefined]) => IteratorResult'. !!! error TS2345: Types of parameters '__0' and '__0' are incompatible. !!! error TS2345: Type '[] | [undefined]' is not assignable to type '[] | [boolean]'. !!! error TS2345: Type '[undefined]' is not assignable to type '[] | [boolean]'. @@ -161,4 +161,13 @@ builtinIterator.ts(73,35): error TS2322: Type 'Generator; const iter1 = Iterator.from(g1); declare const iter2: IteratorObject; -const iter3 = iter2.flatMap(() => g1); +const iter3 = iter2.flatMap(() => g1); + +// Iterator.from pass-through of return value +const customGenerator = function* () { + return 42; +}(); +const withHelpers = Iterator.from(customGenerator); +const result = withHelpers.next(); +const resultValue: number = result.value; // this should work + //// [builtinIterator.js] "use strict"; @@ -134,3 +143,10 @@ class BadIterator3 extends Iterator { } const iter1 = Iterator.from(g1); const iter3 = iter2.flatMap(() => g1); +// Iterator.from pass-through of return value +const customGenerator = function* () { + return 42; +}(); +const withHelpers = Iterator.from(customGenerator); +const result = withHelpers.next(); +const resultValue = result.value; // this should work diff --git a/tests/baselines/reference/builtinIterator.symbols b/tests/baselines/reference/builtinIterator.symbols index 34ba5eea534dd..2a76a6bd4b739 100644 --- a/tests/baselines/reference/builtinIterator.symbols +++ b/tests/baselines/reference/builtinIterator.symbols @@ -193,3 +193,28 @@ const iter3 = iter2.flatMap(() => g1); >flatMap : Symbol(IteratorObject.flatMap, Decl(lib.esnext.iterator.d.ts, --, --)) >g1 : Symbol(g1, Decl(builtinIterator.ts, 68, 13)) +// Iterator.from pass-through of return value +const customGenerator = function* () { +>customGenerator : Symbol(customGenerator, Decl(builtinIterator.ts, 75, 5)) + + return 42; +}(); +const withHelpers = Iterator.from(customGenerator); +>withHelpers : Symbol(withHelpers, Decl(builtinIterator.ts, 78, 5)) +>Iterator.from : Symbol(IteratorConstructor.from, Decl(lib.esnext.iterator.d.ts, --, --)) +>Iterator : Symbol(Iterator, Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.esnext.iterator.d.ts, --, --)) +>from : Symbol(IteratorConstructor.from, Decl(lib.esnext.iterator.d.ts, --, --)) +>customGenerator : Symbol(customGenerator, Decl(builtinIterator.ts, 75, 5)) + +const result = withHelpers.next(); +>result : Symbol(result, Decl(builtinIterator.ts, 79, 5)) +>withHelpers.next : Symbol(Iterator.next, Decl(lib.es2015.iterable.d.ts, --, --)) +>withHelpers : Symbol(withHelpers, Decl(builtinIterator.ts, 78, 5)) +>next : Symbol(Iterator.next, Decl(lib.es2015.iterable.d.ts, --, --)) + +const resultValue: number = result.value; // this should work +>resultValue : Symbol(resultValue, Decl(builtinIterator.ts, 80, 5)) +>result.value : Symbol(value, Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --)) +>result : Symbol(result, Decl(builtinIterator.ts, 79, 5)) +>value : Symbol(value, Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --)) + diff --git a/tests/baselines/reference/builtinIterator.types b/tests/baselines/reference/builtinIterator.types index 75d934cddae8c..e79a40cbd2537 100644 --- a/tests/baselines/reference/builtinIterator.types +++ b/tests/baselines/reference/builtinIterator.types @@ -6,12 +6,12 @@ const iterator = Iterator.from([0, 1, 2]); > : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ >Iterator.from([0, 1, 2]) : IteratorObject > : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ->Iterator.from : (value: Iterator | Iterable) => IteratorObject -> : ^ ^^ ^^ ^^^^^ +>Iterator.from : (value: Iterator | Iterable) => IteratorObject +> : ^ ^^ ^^^^^^^^ ^^ ^^^^^ >Iterator : IteratorConstructor > : ^^^^^^^^^^^^^^^^^^^ ->from : (value: Iterator | Iterable) => IteratorObject -> : ^ ^^ ^^ ^^^^^ +>from : (value: Iterator | Iterable) => IteratorObject +> : ^ ^^ ^^^^^^^^ ^^ ^^^^^ >[0, 1, 2] : number[] > : ^^^^^^^^ >0 : 0 @@ -86,16 +86,16 @@ const zero = iterator.filter(isZero); > : ^ ^^ ^^^^^ const iteratorFromBare = Iterator.from({ ->iteratorFromBare : IteratorObject -> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ->Iterator.from({ next() { return { done: Math.random() < .5, value: "a string", }; },}) : IteratorObject -> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ->Iterator.from : (value: Iterator | Iterable) => IteratorObject -> : ^ ^^ ^^ ^^^^^ +>iteratorFromBare : IteratorObject +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>Iterator.from({ next() { return { done: Math.random() < .5, value: "a string", }; },}) : IteratorObject +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>Iterator.from : (value: Iterator | Iterable) => IteratorObject +> : ^ ^^ ^^^^^^^^ ^^ ^^^^^ >Iterator : IteratorConstructor > : ^^^^^^^^^^^^^^^^^^^ ->from : (value: Iterator | Iterable) => IteratorObject -> : ^ ^^ ^^ ^^^^^ +>from : (value: Iterator | Iterable) => IteratorObject +> : ^ ^^ ^^^^^^^^ ^^ ^^^^^ >{ next() { return { done: Math.random() < .5, value: "a string", }; },} : { next(): { done: boolean; value: string; }; } > : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -393,16 +393,16 @@ declare const g1: Generator; > : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ const iter1 = Iterator.from(g1); ->iter1 : IteratorObject -> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ->Iterator.from(g1) : IteratorObject -> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ->Iterator.from : (value: Iterator | Iterable) => IteratorObject -> : ^ ^^ ^^ ^^^^^ +>iter1 : IteratorObject +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>Iterator.from(g1) : IteratorObject +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>Iterator.from : (value: Iterator | Iterable) => IteratorObject +> : ^ ^^ ^^^^^^^^ ^^ ^^^^^ >Iterator : IteratorConstructor > : ^^^^^^^^^^^^^^^^^^^ ->from : (value: Iterator | Iterable) => IteratorObject -> : ^ ^^ ^^ ^^^^^ +>from : (value: Iterator | Iterable) => IteratorObject +> : ^ ^^ ^^^^^^^^ ^^ ^^^^^ >g1 : Generator > : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -426,3 +426,53 @@ const iter3 = iter2.flatMap(() => g1); >g1 : Generator > : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +// Iterator.from pass-through of return value +const customGenerator = function* () { +>customGenerator : Generator +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>function* () { return 42;}() : Generator +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>function* () { return 42;} : () => Generator +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + return 42; +>42 : 42 +> : ^^ + +}(); +const withHelpers = Iterator.from(customGenerator); +>withHelpers : IteratorObject +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>Iterator.from(customGenerator) : IteratorObject +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>Iterator.from : (value: Iterator | Iterable) => IteratorObject +> : ^ ^^ ^^^^^^^^ ^^ ^^^^^ +>Iterator : IteratorConstructor +> : ^^^^^^^^^^^^^^^^^^^ +>from : (value: Iterator | Iterable) => IteratorObject +> : ^ ^^ ^^^^^^^^ ^^ ^^^^^ +>customGenerator : Generator +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +const result = withHelpers.next(); +>result : IteratorResult +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>withHelpers.next() : IteratorResult +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>withHelpers.next : (...[value]: [] | [unknown]) => IteratorResult +> : ^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>withHelpers : IteratorObject +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>next : (...[value]: [] | [unknown]) => IteratorResult +> : ^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +const resultValue: number = result.value; // this should work +>resultValue : number +> : ^^^^^^ +>result.value : number +> : ^^^^^^ +>result : IteratorResult +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>value : number +> : ^^^^^^ + diff --git a/tests/baselines/reference/usingDeclarationsWithIteratorObject.types b/tests/baselines/reference/usingDeclarationsWithIteratorObject.types index ae0dcfe5b55db..04d211f532415 100644 --- a/tests/baselines/reference/usingDeclarationsWithIteratorObject.types +++ b/tests/baselines/reference/usingDeclarationsWithIteratorObject.types @@ -56,12 +56,12 @@ function f() { > : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ >Iterator.from(i) : IteratorObject > : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ->Iterator.from : (value: Iterator | Iterable) => IteratorObject -> : ^ ^^ ^^ ^^^^^ +>Iterator.from : (value: Iterator | Iterable) => IteratorObject +> : ^ ^^ ^^^^^^^^ ^^ ^^^^^ >Iterator : IteratorConstructor > : ^^^^^^^^^^^^^^^^^^^ ->from : (value: Iterator | Iterable) => IteratorObject -> : ^ ^^ ^^ ^^^^^ +>from : (value: Iterator | Iterable) => IteratorObject +> : ^ ^^ ^^^^^^^^ ^^ ^^^^^ >i : Iterator > : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/cases/compiler/builtinIterator.ts b/tests/cases/compiler/builtinIterator.ts index e80bda3e44ab1..91f1b028c7fe9 100644 --- a/tests/cases/compiler/builtinIterator.ts +++ b/tests/cases/compiler/builtinIterator.ts @@ -73,4 +73,12 @@ declare const g1: Generator; const iter1 = Iterator.from(g1); declare const iter2: IteratorObject; -const iter3 = iter2.flatMap(() => g1); \ No newline at end of file +const iter3 = iter2.flatMap(() => g1); + +// Iterator.from pass-through of return value +const customGenerator = function* () { + return 42; +}(); +const withHelpers = Iterator.from(customGenerator); +const result = withHelpers.next(); +const resultValue: number = result.value; // this should work