feat: add iterator methods to esnext - #64095
feat: add iterator methods to esnext#64095Oleksandr Tarasiuk (a-tarasyuk) wants to merge 2 commits into
Conversation
There was a problem hiding this comment.
Pull request overview
Adds ESNext declarations for recent iterator proposals and integrates the new library into compiler resolution and bundling.
Changes:
- Adds
chunks,join,includes,zip, andzipKeyeddeclarations. - Registers and embeds
lib.esnext.iterator.d.ts. - Adds compiler tests and updates generated baselines.
Reviewed changes
Copilot reviewed 35 out of 40 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
tsc/internal/bundled/embed_generated.go |
Embeds the new iterator library. |
tsc/internal/bundled/libs/lib.esnext.d.ts |
References the iterator library. |
tsc/internal/bundled/libs/lib.esnext.iterator.d.ts |
Declares the new iterator APIs. |
tsc/internal/bundled/libs_generated.go |
Registers the bundled library name. |
tsc/internal/compiler/program_test.go |
Adds the library to ESNext test expectations. |
tsc/internal/tsoptions/enummaps.go |
Maps esnext.iterator to the new library. |
tsc/testdata/tests/cases/compiler/iteratorChunks.ts |
Tests Iterator.prototype.chunks. |
tsc/testdata/tests/cases/compiler/iteratorIncludes.ts |
Tests Iterator.prototype.includes. |
tsc/testdata/tests/cases/compiler/iteratorJoin.ts |
Tests Iterator.prototype.join. |
tsc/testdata/tests/cases/compiler/iteratorZip.ts |
Tests Iterator.zip and zipKeyed. |
tsc/testdata/baselines/reference/compiler/iteratorChunks.js |
Records chunks emit. |
tsc/testdata/baselines/reference/compiler/iteratorChunks.symbols |
Records chunks symbols. |
tsc/testdata/baselines/reference/compiler/iteratorChunks.types |
Records chunks types. |
tsc/testdata/baselines/reference/compiler/iteratorIncludes.js |
Records includes emit. |
tsc/testdata/baselines/reference/compiler/iteratorIncludes.symbols |
Records includes symbols. |
tsc/testdata/baselines/reference/compiler/iteratorIncludes.types |
Records includes types. |
tsc/testdata/baselines/reference/compiler/iteratorJoin.js |
Records join emit. |
tsc/testdata/baselines/reference/compiler/iteratorJoin.symbols |
Records join symbols. |
tsc/testdata/baselines/reference/compiler/iteratorJoin.types |
Records join types. |
tsc/testdata/baselines/reference/compiler/iteratorZip.js |
Records zip emit. |
tsc/testdata/baselines/reference/compiler/iteratorZip.symbols |
Records zip symbols. |
tsc/testdata/baselines/reference/compiler/iteratorZip.types |
Records zip types. |
tsc/testdata/baselines/reference/compiler/builtinIterator.symbols |
Updates merged iterator symbols. |
tsc/testdata/baselines/reference/compiler/builtinIterator.types |
Updates displayed iterator signatures. |
tsc/testdata/baselines/reference/compiler/libReplacement(libreplacement=true).trace.json |
Records replacement lookup for the new library. |
tsc/testdata/baselines/reference/conformance/awaitUsingDeclarationsWithIteratorObject.symbols |
Updates merged iterator symbols. |
tsc/testdata/baselines/reference/conformance/awaitUsingDeclarationsWithIteratorObject.types |
Updates displayed iterator signatures. |
tsc/testdata/baselines/reference/conformance/usingDeclarationsWithIteratorObject.symbols |
Updates merged iterator symbols. |
tsc/testdata/baselines/reference/conformance/usingDeclarationsWithIteratorObject.types |
Updates displayed iterator signatures. |
tsc/testdata/baselines/reference/tsc/commandLine/Initialized-TSConfig-with-incorrect-compiler-option-value.js |
Updates valid-library diagnostics. |
tsc/testdata/baselines/reference/tsc/commandLine/help-all.js |
Updates library help output. |
tsc/testdata/baselines/reference/tsc/commandLine/help.js |
Updates library help output. |
tsc/testdata/baselines/reference/tsc/commandLine/show-help-with-ExitStatus.DiagnosticsPresent_OutputsSkipped-when-host-cannot-provide-terminal-width.js |
Updates library help output. |
tsc/testdata/baselines/reference/tsc/commandLine/show-help-with-ExitStatus.DiagnosticsPresent_OutputsSkipped.js |
Updates wrapped library help output. |
tsc/testdata/baselines/reference/tsc/ignoreConfig/without-any-options-when-config-file-absent-with---ignoreConfig.js |
Updates library help output. |
tsc/testdata/baselines/reference/tsc/ignoreConfig/without-any-options-when-config-file-absent.js |
Updates library help output. |
tsc/testdata/baselines/reference/tsc/showConfig/Show-TSConfig-with-incorrect-compiler-option-value.js |
Updates valid-library diagnostics. |
tsc/testdata/baselines/reference/tscWatch/commandLine/Parse-watch-interval-option-without-tsconfig.json.js |
Updates library help output. |
tsc/testdata/baselines/reference/tscWatch/commandLineWatch/watch-handles-tsconfig-deleted.js |
Updates watched help output. |
tsc/testdata/baselines/reference/tsoptions/commandLineParsing/parseCommandLine/Parse invalid option of library flags.js |
Updates valid-library diagnostics. |
Files not reviewed (3)
- tsc/internal/bundled/embed_generated.go: Generated file
- tsc/internal/bundled/libs_generated.go: Generated file
- tsc/testdata/baselines/reference/tsc/commandLine/Initialized-TSConfig-with-incorrect-compiler-option-value.js: Generated file
💡 Add a code-review agent skill for context-aware, tailored reviews. Learn more in the docs.
Daniel Rosenwasser (DanielRosenwasser)
left a comment
There was a problem hiding this comment.
I don't know if you need to add a bunch more overloads yet, but I think there are a few places that can be simplified for now.
| mode: "strict"; | ||
| } | ||
|
|
||
| type IteratorZipOptions<T> = IteratorZipShortestOptions | IteratorZipLongestOptions<T> | IteratorZipStrictOptions; |
There was a problem hiding this comment.
| type IteratorZipOptions<T> = IteratorZipShortestOptions | IteratorZipLongestOptions<T> | IteratorZipStrictOptions; | |
| type IteratorZipOptions<T> = | |
| | IteratorZipShortestOptions | |
| | IteratorZipLongestOptions<T> | |
| | IteratorZipStrictOptions; |
| // @ts-expect-error padding is only used in longest mode | ||
| Iterator.zip([[1]], { mode: "shortest", padding: [1] }); | ||
|
|
||
| // @ts-expect-error the input must be iterable |
There was a problem hiding this comment.
The tests shouldn't contain ts-expect-error, because the point of our baselines is that we should know precisely what errors are being reported.
There was a problem hiding this comment.
I've removed @ts-expect-error. I found the same pattern used here: https://github.com/microsoft/TypeScript/blob/main/tsc/testdata/tests/cases/compiler/promiseTry.ts
| * @param iterables An iterable of iterators or iterables to zip. | ||
| * @param options Controls how differing input lengths are handled. | ||
| */ | ||
| zip(iterables: readonly [], options?: IteratorZipOptions<Iterable<unknown>>): IteratorObject<never, undefined, unknown>; |
There was a problem hiding this comment.
It is a little funny that we need this overload. I don't know what we'd do instead other than a conditional.
There was a problem hiding this comment.
I actually don't see any test for an empty list of iterables.
There was a problem hiding this comment.
I've added additional tests
|
|
||
| type IteratorZipKeyedResult<T extends { readonly [K in keyof T]: IteratorInput<unknown> }> = { | ||
| -readonly [K in keyof T]: IteratorYield<T[K]>; | ||
| }; |
There was a problem hiding this comment.
Is there a difference in these mapped types other than the constraint? I think you can unify them.
There was a problem hiding this comment.
Done - unified both types into IteratorZipResult
| * @param iterables An iterable of iterators or iterables to zip. | ||
| * @param options Controls how differing input lengths are handled. | ||
| */ | ||
| zip<T extends readonly IteratorInput<unknown>[] | []>(iterables: T, options?: IteratorZipOptions<NoInfer<Partial<IteratorZipResult<T>>>>): IteratorObject<IteratorZipResult<T>, undefined, unknown>; |
There was a problem hiding this comment.
Technically the return type here is a little inaccurate.
When mode is "shortest" or "strict", you'll get fully defined elements in every result.
When mode is "longest", but the padding` is completely filled out, the same is true.
But when "longest" is selected but padding isn't provided, or isn't fully provided, then you can actually witness undefineds.
There was a problem hiding this comment.
I don't know what we should do here. This is already getting very unwieldy, but maybe we just add another overload?
There was a problem hiding this comment.
I've added overloads so undefined only appears for the longest mode with missing or partial padding.
| type IteratorYield<T extends IteratorInput<unknown>> = | ||
| T extends Iterable<infer U, any, any> ? U : | ||
| T extends Iterator<infer U, any, any> ? U : | ||
| never; |
There was a problem hiding this comment.
| type IteratorYield<T extends IteratorInput<unknown>> = | |
| T extends Iterable<infer U, any, any> ? U : | |
| T extends Iterator<infer U, any, any> ? U : | |
| never; | |
| type IteratorYield<T extends IteratorInput<unknown>> = | |
| T extends Iterable<infer U, any, any> | Iterator<infer U, any, any> ? U : | |
| never; |
or possibly just
| type IteratorYield<T extends IteratorInput<unknown>> = | |
| T extends Iterable<infer U, any, any> ? U : | |
| T extends Iterator<infer U, any, any> ? U : | |
| never; | |
| type IteratorYield<T extends IteratorInput<unknown>> = | |
| T extends IteratorInput<infer U> ? U : never; |
|
|
||
| interface IteratorZipStrictOptions { | ||
| /** | ||
| * Requires every input to yield the same number of values. |
There was a problem hiding this comment.
| * Requires every input to yield the same number of values. | |
| * Requires every input to yield the same number of values. | |
| * If not, a `TypeError` will be thrown when an input is exhausted before others. |
| -readonly [K in keyof T]: IteratorYield<T[K]>; | ||
| }; | ||
|
|
||
| type IteratorZipKeyedResult<T extends { readonly [K in keyof T]: IteratorInput<unknown> }> = { |
There was a problem hiding this comment.
Is this circular constraint intentional? I'm surprised it worked. I guess you could simplify a little bit with Record<PropertyKey, IteratorInput<unknown>>
There was a problem hiding this comment.
I removed the circular constraint and reused IteratorZipResult
Fixes #63700