1// @strict: true 2// @declaration: true 3 4// Variadics in tuple types 5 6type TV0<T extends unknown[]> = [string, ...T]; 7type TV1<T extends unknown[]> = [string, ...T, number]; 8type TV2<T extends unknown[]> = [string, ...T, number, ...T]; 9type TV3<T extends unknown[]> = [string, ...T, ...number[], ...T]; 10 11// Normalization 12 13type TN1 = TV1<[boolean, string]>; 14type TN2 = TV1<[]>; 15type TN3 = TV1<[boolean?]>; 16type TN4 = TV1<string[]>; 17type TN5 = TV1<[boolean] | [symbol, symbol]>; 18type TN6 = TV1<any>; 19type TN7 = TV1<never>; 20 21// Variadics in array literals 22 23function tup2<T extends unknown[], U extends unknown[]>(t: [...T], u: [...U]) { 24 return [1, ...t, 2, ...u, 3] as const; 25} 26 27const t2 = tup2(['hello'], [10, true]); 28 29function concat<T extends unknown[], U extends unknown[]>(t: [...T], u: [...U]): [...T, ...U] { 30 return [...t, ...u]; 31} 32 33declare const sa: string[]; 34 35const tc1 = concat([], []); 36const tc2 = concat(['hello'], [42]); 37const tc3 = concat([1, 2, 3], sa); 38const tc4 = concat(sa, [1, 2, 3]); // Ideally would be [...string[], number, number, number] 39 40function concat2<T extends readonly unknown[], U extends readonly unknown[]>(t: T, u: U) { 41 return [...t, ...u]; // (T[number] | U[number])[] 42} 43 44const tc5 = concat2([1, 2, 3] as const, [4, 5, 6] as const); // (1 | 2 | 3 | 4 | 5 | 6)[] 45 46// Spread arguments 47 48declare function foo1(a: number, b: string, c: boolean, ...d: number[]): void; 49 50function foo2(t1: [number, string], t2: [boolean], a1: number[]) { 51 foo1(1, 'abc', true, 42, 43, 44); 52 foo1(...t1, true, 42, 43, 44); 53 foo1(...t1, ...t2, 42, 43, 44); 54 foo1(...t1, ...t2, ...a1); 55 foo1(...t1); // Error 56 foo1(...t1, 45); // Error 57} 58 59declare function foo3<T extends unknown[]>(x: number, ...args: [...T, number]): T; 60 61function foo4<U extends unknown[]>(u: U) { 62 foo3(1, 2); 63 foo3(1, 'hello', true, 2); 64 foo3(1, ...u, 'hi', 2); 65 foo3(1); 66} 67 68// Contextual typing of array literals 69 70declare function ft1<T extends unknown[]>(t: T): T; 71declare function ft2<T extends unknown[]>(t: T): readonly [...T]; 72declare function ft3<T extends unknown[]>(t: [...T]): T; 73declare function ft4<T extends unknown[]>(t: [...T]): readonly [...T]; 74 75ft1(['hello', 42]); // (string | number)[] 76ft2(['hello', 42]); // readonly (string | number)[] 77ft3(['hello', 42]); // [string, number] 78ft4(['hello', 42]); // readonly [string, number] 79 80// Indexing variadic tuple types 81 82function f0<T extends unknown[]>(t: [string, ...T], n: number) { 83 const a = t[0]; // string 84 const b = t[1]; // [string, ...T][1] 85 const c = t[2]; // [string, ...T][2] 86 const d = t[n]; // [string, ...T][number] 87} 88 89function f1<T extends unknown[]>(t: [string, ...T, number], n: number) { 90 const a = t[0]; // string 91 const b = t[1]; // [string, ...T, number][1] 92 const c = t[2]; // [string, ...T, number][2] 93 const d = t[n]; // [string, ...T, number][number] 94} 95 96// Destructuring variadic tuple types 97 98function f2<T extends unknown[]>(t: [string, ...T]) { 99 let [...ax] = t; // [string, ...T] 100 let [b1, ...bx] = t; // string, [...T] 101 let [c1, c2, ...cx] = t; // string, [string, ...T][1], T[number][] 102} 103 104function f3<T extends unknown[]>(t: [string, ...T, number]) { 105 let [...ax] = t; // [string, ...T, number] 106 let [b1, ...bx] = t; // string, [...T, number] 107 let [c1, c2, ...cx] = t; // string, [string, ...T, number][1], (number | T[number])[] 108} 109 110// Mapped types applied to variadic tuple types 111 112type Arrayify<T> = { [P in keyof T]: T[P][] }; 113 114type TM1<U extends unknown[]> = Arrayify<readonly [string, number?, ...U, ...boolean[]]>; // [string[], (number | undefined)[]?, Arrayify<U>, ...boolean[][]] 115 116type TP1<T extends unknown[]> = Partial<[string, ...T, number]>; // [string?, Partial<T>, number?] 117type TP2<T extends unknown[]> = Partial<[string, ...T, ...number[]]>; // [string?, Partial<T>, ...(number | undefined)[]] 118 119// Reverse mapping through mapped type applied to variadic tuple type 120 121declare function fm1<T extends unknown[]>(t: Arrayify<[string, number, ...T]>): T; 122 123let tm1 = fm1([['abc'], [42], [true], ['def']]); // [boolean, string] 124 125// Spread of readonly array-like infers mutable array-like 126 127declare function fx1<T extends unknown[]>(a: string, ...args: T): T; 128 129function gx1<U extends unknown[], V extends readonly unknown[]>(u: U, v: V) { 130 fx1('abc'); // [] 131 fx1('abc', ...u); // U 132 fx1('abc', ...v); // [...V] 133 fx1<U>('abc', ...u); // U 134 fx1<V>('abc', ...v); // Error 135} 136 137declare function fx2<T extends readonly unknown[]>(a: string, ...args: T): T; 138 139function gx2<U extends unknown[], V extends readonly unknown[]>(u: U, v: V) { 140 fx2('abc'); // [] 141 fx2('abc', ...u); // U 142 fx2('abc', ...v); // [...V] 143 fx2<U>('abc', ...u); // U 144 fx2<V>('abc', ...v); // V 145} 146 147// Relations involving variadic tuple types 148 149function f10<T extends string[], U extends T>(x: [string, ...unknown[]], y: [string, ...T], z: [string, ...U]) { 150 x = y; 151 x = z; 152 y = x; // Error 153 y = z; 154 z = x; // Error 155 z = y; // Error 156} 157 158// For a generic type T, [...T] is assignable to T, T is assignable to readonly [...T], and T is assignable 159// to [...T] when T is constrained to a mutable array or tuple type. 160 161function f11<T extends unknown[]>(t: T, m: [...T], r: readonly [...T]) { 162 t = m; 163 t = r; // Error 164 m = t; 165 m = r; // Error 166 r = t; 167 r = m; 168} 169 170function f12<T extends readonly unknown[]>(t: T, m: [...T], r: readonly [...T]) { 171 t = m; 172 t = r; // Error 173 m = t; // Error 174 m = r; // Error 175 r = t; 176 r = m; 177} 178 179function f13<T extends string[], U extends T>(t0: T, t1: [...T], t2: [...U]) { 180 t0 = t1; 181 t0 = t2; 182 t1 = t0; 183 t1 = t2; 184 t2 = t0; // Error 185 t2 = t1; // Error 186} 187 188function f14<T extends readonly string[], U extends T>(t0: T, t1: [...T], t2: [...U]) { 189 t0 = t1; 190 t0 = t2; 191 t1 = t0; // Error 192 t1 = t2; 193 t2 = t0; // Error 194 t2 = t1; // Error 195} 196 197function f15<T extends string[], U extends T>(k0: keyof T, k1: keyof [...T], k2: keyof [...U], k3: keyof [1, 2, ...T]) { 198 k0 = 'length'; 199 k1 = 'length'; 200 k2 = 'length'; 201 k0 = 'slice'; 202 k1 = 'slice'; 203 k2 = 'slice'; 204 k3 = '0'; 205 k3 = '1'; 206 k3 = '2'; // Error 207} 208 209// Inference between variadic tuple types 210 211type First<T extends readonly unknown[]> = 212 T extends readonly [unknown, ...unknown[]] ? T[0] : 213 T[0] | undefined; 214 215type DropFirst<T extends readonly unknown[]> = T extends readonly [unknown?, ...infer U] ? U : [...T]; 216 217type Last<T extends readonly unknown[]> = 218 T extends readonly [...unknown[], infer U] ? U : 219 T extends readonly [unknown, ...unknown[]] ? T[number] : 220 T[number] | undefined; 221 222type DropLast<T extends readonly unknown[]> = T extends readonly [...infer U, unknown] ? U : [...T]; 223 224type T00 = First<[number, symbol, string]>; 225type T01 = First<[symbol, string]>; 226type T02 = First<[string]>; 227type T03 = First<[number, symbol, ...string[]]>; 228type T04 = First<[symbol, ...string[]]>; 229type T05 = First<[string?]>; 230type T06 = First<string[]>; 231type T07 = First<[]>; 232type T08 = First<any>; 233type T09 = First<never>; 234 235type T10 = DropFirst<[number, symbol, string]>; 236type T11 = DropFirst<[symbol, string]>; 237type T12 = DropFirst<[string]>; 238type T13 = DropFirst<[number, symbol, ...string[]]>; 239type T14 = DropFirst<[symbol, ...string[]]>; 240type T15 = DropFirst<[string?]>; 241type T16 = DropFirst<string[]>; 242type T17 = DropFirst<[]>; 243type T18 = DropFirst<any>; 244type T19 = DropFirst<never>; 245 246type T20 = Last<[number, symbol, string]>; 247type T21 = Last<[symbol, string]>; 248type T22 = Last<[string]>; 249type T23 = Last<[number, symbol, ...string[]]>; 250type T24 = Last<[symbol, ...string[]]>; 251type T25 = Last<[string?]>; 252type T26 = Last<string[]>; 253type T27 = Last<[]>; 254type T28 = Last<any>; 255type T29 = Last<never>; 256 257type T30 = DropLast<[number, symbol, string]>; 258type T31 = DropLast<[symbol, string]>; 259type T32 = DropLast<[string]>; 260type T33 = DropLast<[number, symbol, ...string[]]>; 261type T34 = DropLast<[symbol, ...string[]]>; 262type T35 = DropLast<[string?]>; 263type T36 = DropLast<string[]>; 264type T37 = DropLast<[]>; // unknown[], maybe should be [] 265type T38 = DropLast<any>; 266type T39 = DropLast<never>; 267 268type R00 = First<readonly [number, symbol, string]>; 269type R01 = First<readonly [symbol, string]>; 270type R02 = First<readonly [string]>; 271type R03 = First<readonly [number, symbol, ...string[]]>; 272type R04 = First<readonly [symbol, ...string[]]>; 273type R05 = First<readonly string[]>; 274type R06 = First<readonly []>; 275 276type R10 = DropFirst<readonly [number, symbol, string]>; 277type R11 = DropFirst<readonly [symbol, string]>; 278type R12 = DropFirst<readonly [string]>; 279type R13 = DropFirst<readonly [number, symbol, ...string[]]>; 280type R14 = DropFirst<readonly [symbol, ...string[]]>; 281type R15 = DropFirst<readonly string[]>; 282type R16 = DropFirst<readonly []>; 283 284type R20 = Last<readonly [number, symbol, string]>; 285type R21 = Last<readonly [symbol, string]>; 286type R22 = Last<readonly [string]>; 287type R23 = Last<readonly [number, symbol, ...string[]]>; 288type R24 = Last<readonly [symbol, ...string[]]>; 289type R25 = Last<readonly string[]>; 290type R26 = Last<readonly []>; 291 292type R30 = DropLast<readonly [number, symbol, string]>; 293type R31 = DropLast<readonly [symbol, string]>; 294type R32 = DropLast<readonly [string]>; 295type R33 = DropLast<readonly [number, symbol, ...string[]]>; 296type R34 = DropLast<readonly [symbol, ...string[]]>; 297type R35 = DropLast<readonly string[]>; 298type R36 = DropLast<readonly []>; 299 300// Inference to [...T, ...U] with implied arity for T 301 302function curry<T extends unknown[], U extends unknown[], R>(f: (...args: [...T, ...U]) => R, ...a: T) { 303 return (...b: U) => f(...a, ...b); 304} 305 306const fn1 = (a: number, b: string, c: boolean, d: string[]) => 0; 307 308const c0 = curry(fn1); // (a: number, b: string, c: boolean, d: string[]) => number 309const c1 = curry(fn1, 1); // (b: string, c: boolean, d: string[]) => number 310const c2 = curry(fn1, 1, 'abc'); // (c: boolean, d: string[]) => number 311const c3 = curry(fn1, 1, 'abc', true); // (d: string[]) => number 312const c4 = curry(fn1, 1, 'abc', true, ['x', 'y']); // () => number 313 314const fn2 = (x: number, b: boolean, ...args: string[]) => 0; 315 316const c10 = curry(fn2); // (x: number, b: boolean, ...args: string[]) => number 317const c11 = curry(fn2, 1); // (b: boolean, ...args: string[]) => number 318const c12 = curry(fn2, 1, true); // (...args: string[]) => number 319const c13 = curry(fn2, 1, true, 'abc', 'def'); // (...args: string[]) => number 320 321const fn3 = (...args: string[]) => 0; 322 323const c20 = curry(fn3); // (...args: string[]) => number 324const c21 = curry(fn3, 'abc', 'def'); // (...args: string[]) => number 325const c22 = curry(fn3, ...sa); // (...args: string[]) => number 326 327// No inference to [...T, ...U] when there is no implied arity 328 329function curry2<T extends unknown[], U extends unknown[], R>(f: (...args: [...T, ...U]) => R, t: [...T], u: [...U]) { 330 return f(...t, ...u); 331} 332 333declare function fn10(a: string, b: number, c: boolean): string[]; 334 335curry2(fn10, ['hello', 42], [true]); 336curry2(fn10, ['hello'], [42, true]); 337 338// Inference to [...T] has higher priority than inference to [...T, number?] 339 340declare function ft<T extends unknown[]>(t1: [...T], t2: [...T, number?]): T; 341 342ft([1, 2, 3], [1, 2, 3]); 343ft([1, 2], [1, 2, 3]); 344ft(['a', 'b'], ['c', 'd']) 345ft(['a', 'b'], ['c', 'd', 42]) 346 347// Last argument is contextually typed 348 349declare function call<T extends unknown[], R>(...args: [...T, (...args: T) => R]): [T, R]; 350 351call('hello', 32, (a, b) => 42); 352call(...sa, (...x) => 42); 353 354// No inference to ending optional elements (except with identical structure) 355 356declare function f20<T extends unknown[] = []>(args: [...T, number?]): T; 357 358function f21<U extends string[]>(args: [...U, number?]) { 359 let v1 = f20(args); // U 360 let v2 = f20(["foo", "bar"]); // [string] 361 let v3 = f20(["foo", 42]); // [string] 362} 363 364declare function f22<T extends unknown[] = []>(args: [...T, number]): T; 365declare function f22<T extends unknown[] = []>(args: [...T]): T; 366 367function f23<U extends string[]>(args: [...U, number]) { 368 let v1 = f22(args); // U 369 let v2 = f22(["foo", "bar"]); // [string, string] 370 let v3 = f22(["foo", 42]); // [string] 371} 372 373// Repro from #39327 374 375interface Desc<A extends unknown[], T> { 376 readonly f: (...args: A) => T; 377 bind<T extends unknown[], U extends unknown[], R>(this: Desc<[...T, ...U], R>, ...args: T): Desc<[...U], R>; 378} 379 380declare const a: Desc<[string, number, boolean], object>; 381const b = a.bind("", 1); // Desc<[boolean], object> 382 383// Repro from #39607 384 385declare function getUser(id: string, options?: { x?: string }): string; 386 387declare function getOrgUser(id: string, orgId: number, options?: { y?: number, z?: boolean }): void; 388 389function callApi<T extends unknown[] = [], U = void>(method: (...args: [...T, object]) => U) { 390 return (...args: [...T]) => method(...args, {}); 391} 392 393callApi(getUser); 394callApi(getOrgUser); 395 396// Repro from #40235 397 398type Numbers = number[]; 399type Unbounded = [...Numbers, boolean]; 400const data: Unbounded = [false, false]; // Error 401 402type U1 = [string, ...Numbers, boolean]; 403type U2 = [...[string, ...Numbers], boolean]; 404type U3 = [...[string, number], boolean]; 405