• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// @strict: true
2// @declaration: true
3
4// Declarations
5
6type V00 = [number, ...string[]];
7type V01 = [...string[], number];
8type V03 = [number, ...string[], number];
9
10type V10 = [number, ...string[], ...boolean[]];  // Error
11type V11 = [number, ...string[], boolean?];  // Error
12type V12 = [number, string?, boolean];  // Error
13
14// Normalization
15
16type Tup3<T extends unknown[], U extends unknown[], V extends unknown[]> = [...T, ...U, ...V];
17
18type V20 = Tup3<[number], string[], [number]>;  // [number, ...string[], number]
19type V21 = Tup3<[number], [string?], [boolean]>;  // [number, string | undefined, boolean]
20type V22 = Tup3<[number], string[], boolean[]>;  // [number, (string | boolean)[]]
21type V23 = Tup3<[number], string[], [boolean?]>;  // [number, (string | boolean | undefined)[]]
22type V24 = Tup3<[number], [boolean?], string[]>;  // [number, boolean?, ...string[]]
23type V25 = Tup3<string[], number[], boolean[]>;  // (string | number | boolean)[]
24type V26 = Tup3<string[], number[], [boolean]>;  // [...(string | number)[], boolean]
25type V27 = Tup3<[number?], [string], [boolean?]>;  // [number | undefined, string, boolean?]
26
27type V30<A extends unknown[]> = Tup3<A, string[], number[]>;  // [...A, ...(string | number)[]]
28type V31<A extends unknown[]> = Tup3<string[], A, number[]>;  // (string | number | A[number])[]
29type V32<A extends unknown[]> = Tup3<string[], number[], A>;  // [...(string | number)[], ...A]
30
31type V40<A extends unknown[]> = Tup3<A, [string?], number[]>;  // [...A, string?, ...number[]]
32type V41<A extends unknown[]> = Tup3<[string?], A, number[]>;  // [string?, ...A, ...number[]]
33type V42<A extends unknown[]> = Tup3<[string?], number[], A>;  // [string?, ...number[], ...A]
34
35type V50<A extends unknown[]> = Tup3<A, string[], [number?]>;  // [...A, ...(string | number | undefined)[]]
36type V51<A extends unknown[]> = Tup3<string[], A, [number?]>;  // (string | number | A[number] | undefined)[]
37type V52<A extends unknown[]> = Tup3<string[], [number?], A>;  // [...(string | number | undefined)[], ...A]
38
39// Assignability
40
41declare let tt1: [...string[], number];
42tt1 = [5];
43tt1 = ['abc', 5];
44tt1 = ['abc', 'def', 5];
45tt1 = ['abc', 'def', 5, 6];  // Error
46
47declare function ft1(...args: [...strs: string[], num: number]): void;
48ft1(5);
49ft1('abc', 5);
50ft1('abc', 'def', 5);
51ft1('abc', 'def', 5, 6);  // Error
52
53declare let tt2: [number, ...string[], number];
54tt2 = [0];  // Error
55tt2 = [0, 1];
56tt2 = [0, 1, 2];  // Error
57tt2 = [0, 'abc', 1];
58tt2 = [0, 'abc', 'def', 1];
59tt2 = [0, 'abc', 1, 'def'];  // Error
60tt2 = [true, 'abc', 'def', 1];  // Error
61tt2 = [0, 'abc', 'def', true];  // Error
62
63declare function ft2(n1: number, ...rest: [...strs: string[], n2: number]): void;
64ft2(0);  // Error
65ft2(0, 1);
66ft2(0, 1, 2);  // Error
67ft2(0, 'abc', 1);
68ft2(0, 'abc', 'def', 1);
69ft2(0, 'abc', 1, 'def');  // Error
70ft2(true, 'abc', 'def', 1);  // Error
71ft2(0, 'abc', 'def', true);  // Error
72
73function ft3<T extends unknown[]>(x: [number, ...T], y: [number, number], z: [number, ...number[]]) {
74    x = y;  // Error
75    x = z;  // Error
76    y = x;  // Error
77    z = x;  // Error
78}
79
80// Inference
81
82function pipe<T extends readonly unknown[]>(...args: [...T, (...values: T) => void]) {
83    const callback = args[args.length - 1] as (...values: T) => void;
84    const values = args.slice(0, -1) as unknown as T;
85    callback(...values);
86}
87
88pipe("foo", 123, true, (a, b, c) => {
89    a;  // string
90    b;  // number
91    c;  // boolean
92})
93
94pipe("foo", 123, true, (...x) => {
95    x;  // [string, number, boolean]
96});
97
98declare const sa: string[];
99
100pipe(...sa, (...x) => {
101    x;  // string[]
102});
103
104pipe(1, ...sa, 2, (...x) => {
105    x;  // [number, ...string[], number]
106    let qq = x[x.length - 1];
107    let ww = x[0]
108});
109
110pipe<number[]>(1, 2, 3, 4);  // Error
111pipe(...sa);  // Error
112
113declare function fn1<T, U>(t: [...unknown[], T, U]): [T, U];
114fn1([]);  // Error
115fn1([1]);  // Error
116fn1([1, 'abc']);  // [number, string]
117fn1([1, 'abc', true]);  // [string, boolean]
118
119declare function fn2<T, U>(t: [T, ...unknown[], U]): [T, U];
120fn2([]);  // Error
121fn2([1]);  // Error
122fn2([1, 'abc']);  // [number, string]
123fn2([1, 'abc', true]);  // [number, boolean]
124
125// Repro from #39595
126
127declare function foo<S extends readonly [string, ...string[]]>(...stringsAndNumber: readonly [...S, number]): [...S, number];
128
129const a1 = foo('blah1', 1);
130const b1 = foo('blah1', 'blah2', 1);
131const c1 = foo(1);  // Error
132const d1 = foo(1, 2);  // Error
133const e1 = foo('blah1', 'blah2', 1, 2, 3);  // Error
134