@@ -40,3 +40,110 @@ expectType<{a?: number; readonly b?: string; readonly c: boolean}>(variation9);
4040// Works with index signatures
4141declare const variation10 : SetRequired < { [ k : string ] : unknown ; a ?: number ; b : string } , 'a' | 'b' > ;
4242expectType < { [ k : string ] : unknown ; a : number ; b : string } > ( variation10 ) ;
43+
44+ // =================
45+ // Works with arrays
46+ // =================
47+
48+ // Empty array
49+ expectType < [ ] > ( { } as SetRequired < [ ] , never > ) ;
50+ expectType < readonly [ ] > ( { } as SetRequired < readonly [ ] , never > ) ;
51+
52+ // All optional elements
53+ expectType < [ string , number ?] > ( { } as SetRequired < [ string ?, number ?] , '0' > ) ;
54+ expectType < [ string , number , boolean ] > ( { } as SetRequired < [ string ?, number ?, boolean ?] , '0' | '1' | '2' > ) ;
55+ expectType < [ ( string | number ) ] > ( { } as SetRequired < [ ( string | number ) ?] , '0' > ) ;
56+
57+ // Works with number `Keys`, string `Keys`, and union of them.
58+ expectType < [ string , number , boolean ?] > ( { } as SetRequired < [ string , number ?, boolean ?] , 1 > ) ;
59+ expectType < [ string , number , boolean , ...number [ ] ] > ( { } as SetRequired < [ string , number ?, boolean ?, ...number [ ] ] , '1' | '2' > ) ;
60+ expectType < readonly [ string , number , boolean ] > ( { } as SetRequired < readonly [ string ?, number ?, boolean ?] , '0' | 1 | 2 > ) ;
61+
62+ // Mix of optional and required elements
63+ expectType < [ string , number , boolean ?] > ( { } as SetRequired < [ string , number ?, boolean ?] , '1' > ) ;
64+ expectType < readonly [ string , number , boolean ] > ( { } as SetRequired < readonly [ string , number ?, boolean ?] , '1' | '2' > ) ;
65+
66+ // Mix of optional and rest elements
67+ expectType < [ string , number ?, boolean ?, ...number [ ] ] > ( { } as SetRequired < [ string ?, number ?, boolean ?, ...number [ ] ] , '0' > ) ;
68+ expectType < [ string , number , boolean , ...number [ ] ] > ( { } as SetRequired < [ string ?, number ?, boolean ?, ...number [ ] ] , '0' | '1' | 2 > ) ;
69+
70+ // Mix of optional, required, and rest elements
71+ expectType < readonly [ string , number , boolean ?, ...number [ ] ] > ( { } as SetRequired < readonly [ string , number ?, boolean ?, ...number [ ] ] , '1' > ) ;
72+ expectType < [ string , number , boolean , ...string [ ] ] > ( { } as SetRequired < [ string , number ?, boolean ?, ...string [ ] ] , '1' | 2 > ) ;
73+
74+ // Works with readonly arrays
75+ expectType < readonly [ ( string | number ) ] > ( { } as SetRequired < readonly [ ( string | number ) ?] , '0' > ) ;
76+ expectType < readonly [ string , number , boolean ?] > ( { } as SetRequired < readonly [ string , number ?, boolean ?] , '1' > ) ;
77+ expectType < readonly [ string , number , boolean , ...number [ ] ] > ( { } as SetRequired < readonly [ string ?, number ?, boolean ?, ...number [ ] ] , '0' | '1' | 2 > ) ;
78+ expectType < readonly [ string , number , boolean , ...string [ ] ] > ( { } as SetRequired < readonly [ string , number ?, boolean ?, ...string [ ] ] , '1' | 2 > ) ;
79+
80+ // Ignores `Keys` that are already required
81+ expectType < [ string , number ?, boolean ?] > ( { } as SetRequired < [ string , number ?, boolean ?] , '0' > ) ;
82+ expectType < readonly [ string , number , boolean ] > ( { } as SetRequired < readonly [ string , number , boolean ] , 1 | 2 > ) ;
83+ expectType < readonly [ string , number , boolean , ...number [ ] ] > ( { } as SetRequired < readonly [ string , number , boolean , ...number [ ] ] , 1 | 2 > ) ;
84+ expectType < [ string , number , boolean , ...number [ ] ] > ( { } as SetRequired < [ string , number ?, boolean ?, ...number [ ] ] , '0' | '1' | '2' > ) ;
85+
86+ // Ignores `Keys` that are out of bounds
87+ expectType < [ ] > ( { } as SetRequired < [ ] , 1 > ) ;
88+ expectType < [ string , number ?, boolean ?] > ( { } as SetRequired < [ string , number ?, boolean ?] , 10 > ) ;
89+ expectType < [ string , number , boolean ] > ( { } as SetRequired < [ string ?, number ?, boolean ?] , 0 | 1 | 2 | 3 | 4 > ) ;
90+ expectType < readonly [ string , number , boolean ?, ...number [ ] ] > ( { } as SetRequired < readonly [ string , number ?, boolean ?, ...number [ ] ] , 10 | 1 > ) ;
91+
92+ // Marks all keys as required, if `Keys` is `any`.
93+ expectType < [ string , number , boolean ] > ( { } as SetRequired < [ string ?, number ?, boolean ?] , any > ) ;
94+ expectType < [ string , number , boolean , ...number [ ] ] > ( { } as SetRequired < [ string , number ?, boolean ?, ...number [ ] ] , any > ) ;
95+ expectType < readonly [ string , number , boolean , ...number [ ] ] > ( { } as SetRequired < readonly [ string , number , boolean , ...number [ ] ] , any > ) ;
96+ expectType < readonly [ string , number , boolean , ...number [ ] ] > ( { } as SetRequired < readonly [ string , number ?, boolean ?, ...number [ ] ] , any > ) ;
97+
98+ // Marks all keys as required, if `Keys` is `number`.
99+ expectType < [ string , number , boolean ] > ( { } as SetRequired < [ string ?, number ?, boolean ?] , number > ) ;
100+ expectType < [ string , number , boolean , ...number [ ] ] > ( { } as SetRequired < [ string , number ?, boolean ?, ...number [ ] ] , number > ) ;
101+ expectType < readonly [ string , number , boolean , ...number [ ] ] > ( { } as SetRequired < readonly [ string , number , boolean , ...number [ ] ] , number > ) ;
102+ expectType < readonly [ string , number , boolean , ...number [ ] ] > ( { } as SetRequired < readonly [ string , number ?, boolean ?, ...number [ ] ] , number > ) ;
103+
104+ // Returns the array as-is, if `Keys` is `never`.
105+ expectType < [ string ?, number ?] > ( { } as SetRequired < [ string ?, number ?] , never > ) ;
106+ expectType < readonly [ string ?, number ?, ...number [ ] ] > ( { } as SetRequired < readonly [ string ?, number ?, ...number [ ] ] , never > ) ;
107+
108+ // Arrays where non-rest elements appear after the rest element are left unchanged, because they can never have optional elements.
109+ expectType < [ ...string [ ] , string | undefined , number ] > ( { } as SetRequired < [ ...string [ ] , string | undefined , number ] , any > ) ;
110+ expectType < [ boolean , ...string [ ] , string , number ] > ( { } as SetRequired < [ boolean , ...string [ ] , string , number ] , any > ) ;
111+
112+ // Preserves `| undefined`, similar to how built-in `Required` works.
113+ expectType < [ string | undefined , number | undefined , boolean ] > ( { } as SetRequired < [ string | undefined , ( number | undefined ) ?, boolean ?] , 0 | 1 | 2 > ) ;
114+ expectType < readonly [ string | undefined , ( number | undefined ) ?, boolean ?] > ( { } as SetRequired < readonly [ ( string | undefined ) ?, ( number | undefined ) ?, boolean ?] , 0 > ) ;
115+
116+ // Optional elements cannot appear after required ones, `Keys` leading to such situations are ignored.
117+ expectType < [ string ?, number ?, boolean ?] > ( { } as SetRequired < [ string ?, number ?, boolean ?] , 1 | 2 > ) ; // `1` and `2` can't be required when `0` is optional
118+ expectType < [ string , number , boolean ?, string ?, string ?] > (
119+ { } as SetRequired < [ string ?, number ?, boolean ?, string ?, string ?] , 0 | 1 | 3 > , // `3` can't be required when `2` is optional
120+ ) ;
121+ expectType < readonly [ string | undefined , number ?, boolean ?, ...string [ ] ] > (
122+ { } as SetRequired < readonly [ string | undefined , number ?, boolean ?, ...string [ ] ] , 2 > , // `2` can't be required when `1` is optional
123+ ) ;
124+
125+ // Works with unions of arrays
126+ expectType < readonly [ ] | [ ] > ( { } as SetRequired < readonly [ ] | [ ] , never > ) ;
127+ expectType < [ ] | readonly [ ( string | number ) ] > ( { } as SetRequired < [ ] | readonly [ ( string | number ) ?] , 0 > ) ;
128+ expectType < [ string ] | [ string , number , boolean ?, ...number [ ] ] | readonly [ string , number , boolean ?] > (
129+ { } as SetRequired < [ string ?] | [ string , number ?, boolean ?, ...number [ ] ] | readonly [ string , number ?, boolean ?] , 0 | 1 > ,
130+ ) ;
131+ expectType < readonly [ number , string ] | [ string , boolean , ...number [ ] ] | readonly [ string , number | undefined , boolean ?, string ?] > (
132+ { } as SetRequired < readonly [ number , string ] | [ string , boolean ?, ...number [ ] ] | readonly [ string , ( number | undefined ) ?, boolean ?, string ?] , 1 | 3 > ,
133+ ) ;
134+ expectType < readonly [ ...number [ ] , number ] | [ string , boolean , ...number [ ] ] | readonly [ string , number | undefined , boolean , string ] > (
135+ { } as SetRequired < readonly [ ...number [ ] , number ] | [ string , boolean ?, ...number [ ] ] | readonly [ string , ( number | undefined ) ?, boolean ?, string ?] , any > ,
136+ ) ;
137+ expectType < readonly string [ ] | [ x : number , y : number ] | [ string , number , ...string [ ] ] > (
138+ { } as SetRequired < readonly string [ ] | [ x : number , y ?: number ] | [ string ?, number ?, ...string [ ] ] , number > ,
139+ ) ;
140+
141+ // Works with labelled tuples
142+ expectType < [ x : string , y : number ] > ( { } as SetRequired < [ x ?: string , y ?: number ] , '0' | '1' > ) ;
143+ expectType < readonly [ x : number , y : number , z ?: number ] > ( { } as SetRequired < readonly [ x ?: number , y ?: number , z ?: number ] , 0 | 1 > ) ;
144+ expectType < readonly [ x : number , y : number , z ?: number , ...rest : number [ ] ] > ( { } as SetRequired < readonly [ x ?: number , y ?: number , z ?: number , ...rest : number [ ] ] , 0 | 1 > ) ;
145+
146+ // Non tuple arrays are left unchanged
147+ expectType < string [ ] > ( { } as SetRequired < string [ ] , number > ) ;
148+ expectType < ReadonlyArray < string | number > > ( { } as SetRequired < ReadonlyArray < string | number > , number > ) ;
149+ expectType < number [ ] > ( { } as SetRequired < [ ...number [ ] ] , never > ) ;
0 commit comments