Skip to content

Commit ac7cdfc

Browse files
committed
update iterator zip typings and test baselines
1 parent 567381d commit ac7cdfc

21 files changed

Lines changed: 731 additions & 184 deletions

‎tsc/internal/bundled/libs/lib.esnext.iterator.d.ts‎

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -40,25 +40,24 @@ interface IteratorZipLongestOptions<T> {
4040
interface IteratorZipStrictOptions {
4141
/**
4242
* Requires every input to yield the same number of values.
43+
* If not, a `TypeError` will be thrown when an input is exhausted before others.
4344
*/
4445
mode: "strict";
4546
}
4647

47-
type IteratorZipOptions<T> = IteratorZipShortestOptions | IteratorZipLongestOptions<T> | IteratorZipStrictOptions;
48+
type IteratorZipOptions<T> =
49+
| IteratorZipShortestOptions
50+
| IteratorZipLongestOptions<T>
51+
| IteratorZipStrictOptions;
4852

4953
type IteratorInput<T> = Iterable<T> | Iterator<T>;
5054

51-
type IteratorYield<T extends IteratorInput<unknown>> =
52-
T extends Iterable<infer U, any, any> ? U :
53-
T extends Iterator<infer U, any, any> ? U :
54-
never;
55+
type IteratorInputTuple = readonly [] | readonly [IteratorInput<unknown>, ...IteratorInput<unknown>[]];
5556

56-
type IteratorZipResult<T extends readonly IteratorInput<unknown>[]> = {
57-
-readonly [K in keyof T]: IteratorYield<T[K]>;
58-
};
57+
type IteratorYield<T> = T extends IteratorInput<infer U> ? U : never;
5958

60-
type IteratorZipKeyedResult<T extends { readonly [K in keyof T]: IteratorInput<unknown> }> = {
61-
-readonly [K in keyof T]: IteratorYield<T[K]>;
59+
type IteratorZipResult<T, TExtra = never> = {
60+
-readonly [K in keyof T]: IteratorYield<T[K]> | TExtra;
6261
};
6362

6463
declare global {
@@ -97,20 +96,24 @@ declare global {
9796
* @param iterables An iterable of iterators or iterables to zip.
9897
* @param options Controls how differing input lengths are handled.
9998
*/
100-
zip<T extends readonly IteratorInput<unknown>[] | []>(iterables: T, options?: IteratorZipOptions<NoInfer<Partial<IteratorZipResult<T>>>>): IteratorObject<IteratorZipResult<T>, undefined, unknown>;
99+
zip<T extends IteratorInputTuple>(iterables: T, options: IteratorZipLongestOptions<NoInfer<IteratorZipResult<T>>> & { padding: NoInfer<IteratorZipResult<T>>; }): IteratorObject<IteratorZipResult<T>, undefined, unknown>;
100+
zip<T extends readonly IteratorInput<unknown>[] | []>(iterables: T, options?: IteratorZipShortestOptions | IteratorZipStrictOptions): IteratorObject<IteratorZipResult<T>, undefined, unknown>;
101+
zip<T extends readonly IteratorInput<unknown>[] | []>(iterables: T, options: IteratorZipOptions<NoInfer<Partial<IteratorZipResult<T>>>>): IteratorObject<IteratorZipResult<T, undefined>, undefined, unknown>;
101102

102103
/**
103104
* Creates an iterator whose values are arrays containing values yielded at the same position by each input iterator or iterable.
104105
* @param iterables An iterable of iterators or iterables to zip.
105106
* @param options Controls how differing input lengths are handled.
106107
*/
107-
zip<T extends IteratorInput<unknown>>(iterables: Iterable<T>, options?: IteratorZipOptions<NoInfer<Iterable<IteratorYield<T>>>>): IteratorObject<IteratorYield<T>[], undefined, unknown>;
108+
zip<T extends IteratorInput<unknown>>(iterables: Iterable<T>, options?: IteratorZipShortestOptions | IteratorZipStrictOptions): IteratorObject<IteratorYield<T>[], undefined, unknown>;
109+
zip<T extends IteratorInput<unknown>>(iterables: Iterable<T>, options: IteratorZipOptions<NoInfer<Iterable<IteratorYield<T>>>>): IteratorObject<(IteratorYield<T> | undefined)[], undefined, unknown>;
108110

109111
/**
110112
* Creates an iterator whose values are objects containing values yielded at the same position by each iterator or iterable in the input object.
111113
* @param iterables An object whose enumerable own properties contain iterators or iterables to zip.
112114
* @param options Controls how differing input lengths are handled.
113115
*/
114-
zipKeyed<T extends { readonly [K in keyof T]: IteratorInput<unknown> }>(iterables: T, options?: IteratorZipOptions<NoInfer<Partial<IteratorZipKeyedResult<T>>>>): IteratorObject<IteratorZipKeyedResult<T>, undefined, unknown>;
116+
zipKeyed<T extends object>(iterables: T & Record<keyof T, IteratorInput<unknown>>, options?: IteratorZipShortestOptions | (IteratorZipLongestOptions<NoInfer<IteratorZipResult<T>>> & { padding: NoInfer<IteratorZipResult<T>>; }) | IteratorZipStrictOptions): IteratorObject<IteratorZipResult<T>, undefined, unknown>;
117+
zipKeyed<T extends object>(iterables: T & Record<keyof T, IteratorInput<unknown>>, options: IteratorZipOptions<NoInfer<Partial<IteratorZipResult<T>>>>): IteratorObject<IteratorZipResult<T, undefined>, undefined, unknown>;
115118
}
116119
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
iteratorChunks.ts(3,33): error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'.
2+
3+
4+
==== iteratorChunks.ts (1 errors) ====
5+
const chunks: number[][] = Iterator.from([1, 2, 3]).chunks(2).toArray();
6+
7+
Iterator.from([1, 2, 3]).chunks("2");
8+
~~~
9+
!!! error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'.
10+

‎tsc/testdata/baselines/reference/compiler/iteratorChunks.js‎

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,10 @@
33
//// [iteratorChunks.ts]
44
const chunks: number[][] = Iterator.from([1, 2, 3]).chunks(2).toArray();
55

6-
// @ts-expect-error chunk size must be a number
76
Iterator.from([1, 2, 3]).chunks("2");
87

98

109
//// [iteratorChunks.js]
1110
"use strict";
1211
const chunks = Iterator.from([1, 2, 3]).chunks(2).toArray();
13-
// @ts-expect-error chunk size must be a number
1412
Iterator.from([1, 2, 3]).chunks("2");

‎tsc/testdata/baselines/reference/compiler/iteratorChunks.symbols‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ const chunks: number[][] = Iterator.from([1, 2, 3]).chunks(2).toArray();
1111
>chunks : Symbol(IteratorObject.chunks, Decl(lib.esnext.iterator.d.ts, --, --))
1212
>toArray : Symbol(IteratorObject.toArray, Decl(lib.es2025.iterator.d.ts, --, --))
1313

14-
// @ts-expect-error chunk size must be a number
1514
Iterator.from([1, 2, 3]).chunks("2");
1615
>Iterator.from([1, 2, 3]).chunks : Symbol(IteratorObject.chunks, Decl(lib.esnext.iterator.d.ts, --, --))
1716
>Iterator.from : Symbol(IteratorConstructor.from, Decl(lib.es2025.iterator.d.ts, --, --))

‎tsc/testdata/baselines/reference/compiler/iteratorChunks.types‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ const chunks: number[][] = Iterator.from([1, 2, 3]).chunks(2).toArray();
1919
>2 : 2
2020
>toArray : () => number[][]
2121

22-
// @ts-expect-error chunk size must be a number
2322
Iterator.from([1, 2, 3]).chunks("2");
2423
>Iterator.from([1, 2, 3]).chunks("2") : IteratorObject<number[], undefined, unknown>
2524
>Iterator.from([1, 2, 3]).chunks : (chunkSize: number) => IteratorObject<number[], undefined, unknown>
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
iteratorIncludes.ts(4,35): error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'.
2+
iteratorIncludes.ts(6,38): error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'.
3+
4+
5+
==== iteratorIncludes.ts (2 errors) ====
6+
const includes: boolean = Iterator.from([1, 2, 3]).includes(2);
7+
const includesAfterSkipping: boolean = Iterator.from([1, 2, 3]).includes(2, 1);
8+
9+
Iterator.from([1, 2, 3]).includes("1");
10+
~~~
11+
!!! error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'.
12+
13+
Iterator.from([1, 2, 3]).includes(2, "1");
14+
~~~
15+
!!! error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'.
16+

‎tsc/testdata/baselines/reference/compiler/iteratorIncludes.js‎

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,14 @@
44
const includes: boolean = Iterator.from([1, 2, 3]).includes(2);
55
const includesAfterSkipping: boolean = Iterator.from([1, 2, 3]).includes(2, 1);
66

7-
// @ts-expect-error the searched value must match the iterator value
87
Iterator.from([1, 2, 3]).includes("1");
98

10-
// @ts-expect-error skipped elements must be a number
119
Iterator.from([1, 2, 3]).includes(2, "1");
1210

1311

1412
//// [iteratorIncludes.js]
1513
"use strict";
1614
const includes = Iterator.from([1, 2, 3]).includes(2);
1715
const includesAfterSkipping = Iterator.from([1, 2, 3]).includes(2, 1);
18-
// @ts-expect-error the searched value must match the iterator value
1916
Iterator.from([1, 2, 3]).includes("1");
20-
// @ts-expect-error skipped elements must be a number
2117
Iterator.from([1, 2, 3]).includes(2, "1");

‎tsc/testdata/baselines/reference/compiler/iteratorIncludes.symbols‎

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,13 @@ const includesAfterSkipping: boolean = Iterator.from([1, 2, 3]).includes(2, 1);
1717
>from : Symbol(IteratorConstructor.from, Decl(lib.es2025.iterator.d.ts, --, --))
1818
>includes : Symbol(IteratorObject.includes, Decl(lib.esnext.iterator.d.ts, --, --))
1919

20-
// @ts-expect-error the searched value must match the iterator value
2120
Iterator.from([1, 2, 3]).includes("1");
2221
>Iterator.from([1, 2, 3]).includes : Symbol(IteratorObject.includes, Decl(lib.esnext.iterator.d.ts, --, --))
2322
>Iterator.from : Symbol(IteratorConstructor.from, Decl(lib.es2025.iterator.d.ts, --, --))
2423
>Iterator : Symbol(Iterator, Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2025.iterator.d.ts, --, --))
2524
>from : Symbol(IteratorConstructor.from, Decl(lib.es2025.iterator.d.ts, --, --))
2625
>includes : Symbol(IteratorObject.includes, Decl(lib.esnext.iterator.d.ts, --, --))
2726

28-
// @ts-expect-error skipped elements must be a number
2927
Iterator.from([1, 2, 3]).includes(2, "1");
3028
>Iterator.from([1, 2, 3]).includes : Symbol(IteratorObject.includes, Decl(lib.esnext.iterator.d.ts, --, --))
3129
>Iterator.from : Symbol(IteratorConstructor.from, Decl(lib.es2025.iterator.d.ts, --, --))

‎tsc/testdata/baselines/reference/compiler/iteratorIncludes.types‎

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ const includesAfterSkipping: boolean = Iterator.from([1, 2, 3]).includes(2, 1);
3232
>2 : 2
3333
>1 : 1
3434

35-
// @ts-expect-error the searched value must match the iterator value
3635
Iterator.from([1, 2, 3]).includes("1");
3736
>Iterator.from([1, 2, 3]).includes("1") : boolean
3837
>Iterator.from([1, 2, 3]).includes : (searchElement: number, skippedElements?: number) => boolean
@@ -47,7 +46,6 @@ Iterator.from([1, 2, 3]).includes("1");
4746
>includes : (searchElement: number, skippedElements?: number) => boolean
4847
>"1" : "1"
4948

50-
// @ts-expect-error skipped elements must be a number
5149
Iterator.from([1, 2, 3]).includes(2, "1");
5250
>Iterator.from([1, 2, 3]).includes(2, "1") : boolean
5351
>Iterator.from([1, 2, 3]).includes : (searchElement: number, skippedElements?: number) => boolean
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
iteratorJoin.ts(4,31): error TS2345: Argument of type 'number' is not assignable to parameter of type 'string'.
2+
3+
4+
==== iteratorJoin.ts (1 errors) ====
5+
const joined: string = Iterator.from([1, 2, 3]).join("-");
6+
const joinedWithDefaultSeparator: string = Iterator.from([1, 2, 3]).join();
7+
8+
Iterator.from([1, 2, 3]).join(0);
9+
~
10+
!!! error TS2345: Argument of type 'number' is not assignable to parameter of type 'string'.
11+

0 commit comments

Comments
 (0)