@@ -114,3 +114,118 @@ Deno.test("isTupleOf<T, R>", async (t) => {
114114 }
115115 } ) ;
116116} ) ;
117+
118+ Deno . test ( "isTupleOf<T, R, L>" , async ( t ) => {
119+ await t . step ( "returns properly named predicate function" , async ( t ) => {
120+ await assertSnapshot (
121+ t ,
122+ isTupleOf ( [ is . Number , is . String , is . Boolean ] , is . Array , [
123+ is . Number ,
124+ is . String ,
125+ is . Boolean ,
126+ ] ) . name ,
127+ ) ;
128+ await assertSnapshot (
129+ t ,
130+ isTupleOf ( [ ( _x ) : _x is string => false ] , is . ArrayOf ( is . String ) , [
131+ ( _x ) : _x is string => false ,
132+ ] )
133+ . name ,
134+ ) ;
135+ await assertSnapshot (
136+ t ,
137+ isTupleOf ( [
138+ isTupleOf (
139+ [ isTupleOf ( [ is . Number , is . String , is . Boolean ] , is . Array ) ] ,
140+ is . Array ,
141+ [ isTupleOf ( [ is . Number , is . String , is . Boolean ] , is . Array ) ] ,
142+ ) ,
143+ ] ) . name ,
144+ ) ;
145+ } ) ;
146+
147+ await t . step ( "returns true on T tuple" , ( ) => {
148+ const predTup = [ is . Number , is . String , is . Boolean ] as const ;
149+ const predRest = is . ArrayOf ( is . Number ) ;
150+ const predTrail = [ is . Number , is . String , is . Boolean ] as const ;
151+ assertEquals (
152+ isTupleOf ( predTup , predRest , predTrail ) ( [ 0 , "a" , true , 0 , "a" , true ] ) ,
153+ true ,
154+ ) ;
155+ assertEquals (
156+ isTupleOf ( predTup , predRest , predTrail ) (
157+ [ 0 , "a" , true , 0 , 1 , 2 , 0 , "a" , true ] ,
158+ ) ,
159+ true ,
160+ ) ;
161+ } ) ;
162+
163+ await t . step ( "returns false on non T tuple" , ( ) => {
164+ const predTup = [ is . Number , is . String , is . Boolean ] as const ;
165+ const predRest = is . ArrayOf ( is . String ) ;
166+ const predTrail = [ is . Number , is . String , is . Boolean ] as const ;
167+ assertEquals (
168+ isTupleOf ( predTup , predRest , predTrail ) ( "a" ) ,
169+ false ,
170+ "Not an array" ,
171+ ) ;
172+ assertEquals (
173+ isTupleOf ( predTup , predRest , predTrail ) ( [ 0 , "a" , true , 0 , "a" ] ) ,
174+ false ,
175+ "Less than `predTup.length + predTrail.length`" ,
176+ ) ;
177+ assertEquals (
178+ isTupleOf ( predTup , predRest , predTrail ) ( [ 0 , 1 , 2 , 0 , 1 , 2 , 0 , 1 , 2 ] ) ,
179+ false ,
180+ "Not match `predTup`, `predRest` and `predTrail`" ,
181+ ) ;
182+ assertEquals (
183+ isTupleOf ( predTup , predRest , predTrail ) ( [ 0 , "a" , true , 0 , "a" , "b" ] ) ,
184+ false ,
185+ "Match `predTup` but not match `predTrail` and no rest elements" ,
186+ ) ;
187+ assertEquals (
188+ isTupleOf ( predTup , predRest , predTrail ) ( [ 0 , "a" , "b" , 0 , "a" , true ] ) ,
189+ false ,
190+ "Match `predTrail` but not match `predTup` and no rest elements" ,
191+ ) ;
192+ assertEquals (
193+ isTupleOf ( predTup , predRest , predTrail ) (
194+ [ 0 , "a" , true , 0 , 1 , 2 , 0 , "a" , true ] ,
195+ ) ,
196+ false ,
197+ "Match `predTup` and `predTrail` but not match `predRest`" ,
198+ ) ;
199+ assertEquals (
200+ isTupleOf ( predTup , predRest , predTrail ) (
201+ [ 0 , "a" , true , "a" , "b" , "c" , 0 , "a" , "b" ] ,
202+ ) ,
203+ false ,
204+ "Match `predTup` and `predRest` but not match `predTrail`" ,
205+ ) ;
206+ assertEquals (
207+ isTupleOf ( predTup , predRest , predTrail ) (
208+ [ 0 , "a" , "b" , "a" , "b" , "c" , 0 , "a" , true ] ,
209+ ) ,
210+ false ,
211+ "Match `predRest` and `predTrail` but not match `predTup`" ,
212+ ) ;
213+ } ) ;
214+
215+ await t . step ( "predicated type is correct" , ( ) => {
216+ const predTup = [ is . Number , is . String , is . Boolean ] as const ;
217+ const predRest = is . ArrayOf ( is . Number ) ;
218+ const predTrail = [ is . Number , is . String , is . Boolean ] as const ;
219+ const a : unknown = [ 0 , "a" , true , 0 , 1 , 2 , 0 , "a" , true ] ;
220+ if ( isTupleOf ( predTup , predRest , predTrail ) ( a ) ) {
221+ assertType <
222+ Equal <
223+ typeof a ,
224+ [ number , string , boolean , ...number [ ] , number , string , boolean ]
225+ >
226+ > (
227+ true ,
228+ ) ;
229+ }
230+ } ) ;
231+ } ) ;
0 commit comments