|
| 1 | +tests/cases/compiler/recursiveConditionalTypes.ts(16,11): error TS2589: Type instantiation is excessively deep and possibly infinite. |
| 2 | +tests/cases/compiler/recursiveConditionalTypes.ts(20,5): error TS2322: Type 'Awaited<T>' is not assignable to type 'Awaited<U>'. |
| 3 | + Type 'T' is not assignable to type 'U'. |
| 4 | + 'U' could be instantiated with an arbitrary type which could be unrelated to 'T'. |
| 5 | +tests/cases/compiler/recursiveConditionalTypes.ts(21,5): error TS2322: Type 'T' is not assignable to type 'Awaited<T>'. |
| 6 | +tests/cases/compiler/recursiveConditionalTypes.ts(22,5): error TS2322: Type 'Awaited<T>' is not assignable to type 'T'. |
| 7 | + 'T' could be instantiated with an arbitrary type which could be unrelated to 'Awaited<T>'. |
| 8 | + Type 'T | (T extends PromiseLike<infer U> ? Awaited<U> : T)' is not assignable to type 'T'. |
| 9 | + 'T' could be instantiated with an arbitrary type which could be unrelated to 'T | (T extends PromiseLike<infer U> ? Awaited<U> : T)'. |
| 10 | + Type 'T extends PromiseLike<infer U> ? Awaited<U> : T' is not assignable to type 'T'. |
| 11 | + 'T' could be instantiated with an arbitrary type which could be unrelated to 'T extends PromiseLike<infer U> ? Awaited<U> : T'. |
| 12 | + Type 'unknown' is not assignable to type 'T'. |
| 13 | + 'T' could be instantiated with an arbitrary type which could be unrelated to 'unknown'. |
| 14 | +tests/cases/compiler/recursiveConditionalTypes.ts(35,11): error TS2589: Type instantiation is excessively deep and possibly infinite. |
| 15 | +tests/cases/compiler/recursiveConditionalTypes.ts(46,12): error TS2589: Type instantiation is excessively deep and possibly infinite. |
| 16 | +tests/cases/compiler/recursiveConditionalTypes.ts(49,5): error TS2322: Type 'TupleOf<number, M>' is not assignable to type 'TupleOf<number, N>'. |
| 17 | + Type 'number extends M ? number[] : _TupleOf<number, M, []>' is not assignable to type 'TupleOf<number, N>'. |
| 18 | + Type 'number[] | _TupleOf<number, M, []>' is not assignable to type 'TupleOf<number, N>'. |
| 19 | + Type 'number[]' is not assignable to type 'TupleOf<number, N>'. |
| 20 | +tests/cases/compiler/recursiveConditionalTypes.ts(50,5): error TS2322: Type 'TupleOf<number, N>' is not assignable to type 'TupleOf<number, M>'. |
| 21 | + Type 'number extends N ? number[] : _TupleOf<number, N, []>' is not assignable to type 'TupleOf<number, M>'. |
| 22 | + Type 'number[] | _TupleOf<number, N, []>' is not assignable to type 'TupleOf<number, M>'. |
| 23 | + Type 'number[]' is not assignable to type 'TupleOf<number, M>'. |
| 24 | +tests/cases/compiler/recursiveConditionalTypes.ts(116,5): error TS2589: Type instantiation is excessively deep and possibly infinite. |
| 25 | +tests/cases/compiler/recursiveConditionalTypes.ts(116,9): error TS2345: Argument of type 'Grow2<[], T>' is not assignable to parameter of type 'Grow1<[], T>'. |
| 26 | + Type '[] | Grow2<[string], T>' is not assignable to type 'Grow1<[], T>'. |
| 27 | + Type '[]' is not assignable to type 'Grow1<[], T>'. |
| 28 | + Type 'Grow2<[string], T>' is not assignable to type 'Grow1<[number], T>'. |
| 29 | + Type '[string] | Grow2<[string, string], T>' is not assignable to type 'Grow1<[number], T>'. |
| 30 | + Type '[string]' is not assignable to type 'Grow1<[number], T>'. |
| 31 | + Type '[string]' is not assignable to type '[number]'. |
| 32 | + Type 'string' is not assignable to type 'number'. |
| 33 | + |
| 34 | + |
| 35 | +==== tests/cases/compiler/recursiveConditionalTypes.ts (10 errors) ==== |
| 36 | + // Awaiting promises |
| 37 | + |
| 38 | + type Awaited<T> = |
| 39 | + T extends null | undefined ? T : |
| 40 | + T extends PromiseLike<infer U> ? Awaited<U> : |
| 41 | + T; |
| 42 | + |
| 43 | + type MyPromise<T> = { |
| 44 | + then<U>(f: ((value: T) => U | PromiseLike<U>) | null | undefined): MyPromise<U>; |
| 45 | + } |
| 46 | + |
| 47 | + type InfinitePromise<T> = Promise<InfinitePromise<T>>; |
| 48 | + |
| 49 | + type P0 = Awaited<Promise<string | Promise<MyPromise<number> | null> | undefined>>; |
| 50 | + type P1 = Awaited<any>; |
| 51 | + type P2 = Awaited<InfinitePromise<number>>; // Error |
| 52 | + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 53 | +!!! error TS2589: Type instantiation is excessively deep and possibly infinite. |
| 54 | + |
| 55 | + function f11<T, U extends T>(tx: T, ta: Awaited<T>, ux: U, ua: Awaited<U>) { |
| 56 | + ta = ua; |
| 57 | + ua = ta; // Error |
| 58 | + ~~ |
| 59 | +!!! error TS2322: Type 'Awaited<T>' is not assignable to type 'Awaited<U>'. |
| 60 | +!!! error TS2322: Type 'T' is not assignable to type 'U'. |
| 61 | +!!! error TS2322: 'U' could be instantiated with an arbitrary type which could be unrelated to 'T'. |
| 62 | + ta = tx; // Error |
| 63 | + ~~ |
| 64 | +!!! error TS2322: Type 'T' is not assignable to type 'Awaited<T>'. |
| 65 | + tx = ta; // Error |
| 66 | + ~~ |
| 67 | +!!! error TS2322: Type 'Awaited<T>' is not assignable to type 'T'. |
| 68 | +!!! error TS2322: 'T' could be instantiated with an arbitrary type which could be unrelated to 'Awaited<T>'. |
| 69 | +!!! error TS2322: Type 'T | (T extends PromiseLike<infer U> ? Awaited<U> : T)' is not assignable to type 'T'. |
| 70 | +!!! error TS2322: 'T' could be instantiated with an arbitrary type which could be unrelated to 'T | (T extends PromiseLike<infer U> ? Awaited<U> : T)'. |
| 71 | +!!! error TS2322: Type 'T extends PromiseLike<infer U> ? Awaited<U> : T' is not assignable to type 'T'. |
| 72 | +!!! error TS2322: 'T' could be instantiated with an arbitrary type which could be unrelated to 'T extends PromiseLike<infer U> ? Awaited<U> : T'. |
| 73 | +!!! error TS2322: Type 'unknown' is not assignable to type 'T'. |
| 74 | +!!! error TS2322: 'T' could be instantiated with an arbitrary type which could be unrelated to 'unknown'. |
| 75 | + } |
| 76 | + |
| 77 | + // Flattening arrays |
| 78 | + |
| 79 | + type Flatten<T extends readonly unknown[]> = T extends unknown[] ? _Flatten<T>[] : readonly _Flatten<T>[]; |
| 80 | + type _Flatten<T> = T extends readonly (infer U)[] ? _Flatten<U> : T; |
| 81 | + |
| 82 | + type InfiniteArray<T> = InfiniteArray<T>[]; |
| 83 | + |
| 84 | + type B0 = Flatten<string[][][]>; |
| 85 | + type B1 = Flatten<string[][] | readonly (number[] | boolean[][])[]>; |
| 86 | + type B2 = Flatten<InfiniteArray<string>>; |
| 87 | + type B3 = B2[0]; // Error |
| 88 | + ~~~~~ |
| 89 | +!!! error TS2589: Type instantiation is excessively deep and possibly infinite. |
| 90 | + |
| 91 | + // Repeating tuples |
| 92 | + |
| 93 | + type TupleOf<T, N extends number> = N extends N ? number extends N ? T[] : _TupleOf<T, N, []> : never; |
| 94 | + type _TupleOf<T, N extends number, R extends unknown[]> = R['length'] extends N ? R : _TupleOf<T, N, [T, ...R]>; |
| 95 | + |
| 96 | + type TT0 = TupleOf<string, 4>; |
| 97 | + type TT1 = TupleOf<number, 0 | 2 | 4>; |
| 98 | + type TT2 = TupleOf<number, number>; |
| 99 | + type TT3 = TupleOf<number, any>; |
| 100 | + type TT4 = TupleOf<number, 100>; // Depth error |
| 101 | + ~~~~~~~~~~~~~~~~~~~~ |
| 102 | +!!! error TS2589: Type instantiation is excessively deep and possibly infinite. |
| 103 | + |
| 104 | + function f22<N extends number, M extends N>(tn: TupleOf<number, N>, tm: TupleOf<number, M>) { |
| 105 | + tn = tm; |
| 106 | + ~~ |
| 107 | +!!! error TS2322: Type 'TupleOf<number, M>' is not assignable to type 'TupleOf<number, N>'. |
| 108 | +!!! error TS2322: Type 'number extends M ? number[] : _TupleOf<number, M, []>' is not assignable to type 'TupleOf<number, N>'. |
| 109 | +!!! error TS2322: Type 'number[] | _TupleOf<number, M, []>' is not assignable to type 'TupleOf<number, N>'. |
| 110 | +!!! error TS2322: Type 'number[]' is not assignable to type 'TupleOf<number, N>'. |
| 111 | + tm = tn; |
| 112 | + ~~ |
| 113 | +!!! error TS2322: Type 'TupleOf<number, N>' is not assignable to type 'TupleOf<number, M>'. |
| 114 | +!!! error TS2322: Type 'number extends N ? number[] : _TupleOf<number, N, []>' is not assignable to type 'TupleOf<number, M>'. |
| 115 | +!!! error TS2322: Type 'number[] | _TupleOf<number, N, []>' is not assignable to type 'TupleOf<number, M>'. |
| 116 | +!!! error TS2322: Type 'number[]' is not assignable to type 'TupleOf<number, M>'. |
| 117 | + } |
| 118 | + |
| 119 | + declare function f23<T>(t: TupleOf<T, 3>): T; |
| 120 | + |
| 121 | + f23(['a', 'b', 'c']); // string |
| 122 | + |
| 123 | + // Inference to recursive type |
| 124 | + |
| 125 | + interface Box<T> { value: T }; |
| 126 | + type RecBox<T> = T | Box<RecBox<T>>; |
| 127 | + type InfBox<T> = Box<InfBox<T>>; |
| 128 | + |
| 129 | + declare function unbox<T>(box: RecBox<T>): T |
| 130 | + |
| 131 | + type T1 = Box<string>; |
| 132 | + type T2 = Box<T1>; |
| 133 | + type T3 = Box<T2>; |
| 134 | + type T4 = Box<T3>; |
| 135 | + type T5 = Box<T4>; |
| 136 | + type T6 = Box<T5>; |
| 137 | + |
| 138 | + declare let b1: Box<Box<Box<Box<Box<Box<string>>>>>>; |
| 139 | + declare let b2: T6; |
| 140 | + declare let b3: InfBox<string>; |
| 141 | + declare let b4: { value: { value: { value: typeof b4 }}}; |
| 142 | + |
| 143 | + unbox(b1); // string |
| 144 | + unbox(b2); // string |
| 145 | + unbox(b3); // InfBox<string> |
| 146 | + unbox({ value: { value: { value: { value: { value: { value: 5 }}}}}}); // number |
| 147 | + unbox(b4); // { value: { value: typeof b4 }} |
| 148 | + unbox({ value: { value: { get value() { return this; } }}}); // { readonly value: ... } |
| 149 | + |
| 150 | + // Inference from nested instantiations of same generic types |
| 151 | + |
| 152 | + type Box1<T> = { value: T }; |
| 153 | + type Box2<T> = { value: T }; |
| 154 | + |
| 155 | + declare function foo<T>(x: Box1<Box1<T>>): T; |
| 156 | + |
| 157 | + declare let z: Box2<Box2<string>>; |
| 158 | + |
| 159 | + foo(z); // unknown, but ideally would be string (requires unique recursion ID for each type reference) |
| 160 | + |
| 161 | + // Intersect tuple element types |
| 162 | + |
| 163 | + type Intersect<U extends any[], R = unknown> = U extends [infer H, ...infer T] ? Intersect<T, R & H> : R; |
| 164 | + |
| 165 | + type QQ = Intersect<[string[], number[], 7]>; |
| 166 | + |
| 167 | + // Infer between structurally identical recursive conditional types |
| 168 | + |
| 169 | + type Unpack1<T> = T extends (infer U)[] ? Unpack1<U> : T; |
| 170 | + type Unpack2<T> = T extends (infer U)[] ? Unpack2<U> : T; |
| 171 | + |
| 172 | + function f20<T, U extends T>(x: Unpack1<T>, y: Unpack2<T>) { |
| 173 | + x = y; |
| 174 | + y = x; |
| 175 | + f20(y, x); |
| 176 | + } |
| 177 | + |
| 178 | + type Grow1<T extends unknown[], N extends number> = T['length'] extends N ? T : Grow1<[number, ...T], N>; |
| 179 | + type Grow2<T extends unknown[], N extends number> = T['length'] extends N ? T : Grow2<[string, ...T], N>; |
| 180 | + |
| 181 | + function f21<T extends number>(x: Grow1<[], T>, y: Grow2<[], T>) { |
| 182 | + f21(y, x); // Error |
| 183 | + ~~~~~~~~~ |
| 184 | +!!! error TS2589: Type instantiation is excessively deep and possibly infinite. |
| 185 | + ~ |
| 186 | +!!! error TS2345: Argument of type 'Grow2<[], T>' is not assignable to parameter of type 'Grow1<[], T>'. |
| 187 | +!!! error TS2345: Type '[] | Grow2<[string], T>' is not assignable to type 'Grow1<[], T>'. |
| 188 | +!!! error TS2345: Type '[]' is not assignable to type 'Grow1<[], T>'. |
| 189 | +!!! error TS2345: Type 'Grow2<[string], T>' is not assignable to type 'Grow1<[number], T>'. |
| 190 | +!!! error TS2345: Type '[string] | Grow2<[string, string], T>' is not assignable to type 'Grow1<[number], T>'. |
| 191 | +!!! error TS2345: Type '[string]' is not assignable to type 'Grow1<[number], T>'. |
| 192 | +!!! error TS2345: Type '[string]' is not assignable to type '[number]'. |
| 193 | +!!! error TS2345: Type 'string' is not assignable to type 'number'. |
| 194 | + } |
| 195 | + |
0 commit comments