1// @strict: true 2// @declaration: true 3// @target: esnext 4 5// Awaiting promises 6 7type Awaited<T> = 8 T extends null | undefined ? T : 9 T extends PromiseLike<infer U> ? Awaited<U> : 10 T; 11 12type MyPromise<T> = { 13 then<U>(f: ((value: T) => U | PromiseLike<U>) | null | undefined): MyPromise<U>; 14} 15 16type InfinitePromise<T> = Promise<InfinitePromise<T>>; 17 18type P0 = Awaited<Promise<string | Promise<MyPromise<number> | null> | undefined>>; 19type P1 = Awaited<any>; 20type P2 = Awaited<InfinitePromise<number>>; // Error 21 22function f11<T, U extends T>(tx: T, ta: Awaited<T>, ux: U, ua: Awaited<U>) { 23 ta = ua; 24 ua = ta; // Error 25 ta = tx; // Error 26 tx = ta; // Error 27} 28 29// Flattening arrays 30 31type Flatten<T extends readonly unknown[]> = T extends unknown[] ? _Flatten<T>[] : readonly _Flatten<T>[]; 32type _Flatten<T> = T extends readonly (infer U)[] ? _Flatten<U> : T; 33 34type InfiniteArray<T> = InfiniteArray<T>[]; 35 36type B0 = Flatten<string[][][]>; 37type B1 = Flatten<string[][] | readonly (number[] | boolean[][])[]>; 38type B2 = Flatten<InfiniteArray<string>>; 39type B3 = B2[0]; // Error 40 41// Repeating tuples 42 43type TupleOf<T, N extends number> = N extends N ? number extends N ? T[] : _TupleOf<T, N, []> : never; 44type _TupleOf<T, N extends number, R extends unknown[]> = R['length'] extends N ? R : _TupleOf<T, N, [T, ...R]>; 45 46type TT0 = TupleOf<string, 4>; 47type TT1 = TupleOf<number, 0 | 2 | 4>; 48type TT2 = TupleOf<number, number>; 49type TT3 = TupleOf<number, any>; 50type TT4 = TupleOf<number, 100>; // Depth error 51 52function f22<N extends number, M extends N>(tn: TupleOf<number, N>, tm: TupleOf<number, M>) { 53 tn = tm; 54 tm = tn; 55} 56 57declare function f23<T>(t: TupleOf<T, 3>): T; 58 59f23(['a', 'b', 'c']); // string 60 61// Inference to recursive type 62 63interface Box<T> { value: T }; 64type RecBox<T> = T | Box<RecBox<T>>; 65type InfBox<T> = Box<InfBox<T>>; 66 67declare function unbox<T>(box: RecBox<T>): T 68 69type T1 = Box<string>; 70type T2 = Box<T1>; 71type T3 = Box<T2>; 72type T4 = Box<T3>; 73type T5 = Box<T4>; 74type T6 = Box<T5>; 75 76declare let b1: Box<Box<Box<Box<Box<Box<string>>>>>>; 77declare let b2: T6; 78declare let b3: InfBox<string>; 79declare let b4: { value: { value: { value: typeof b4 }}}; 80 81unbox(b1); // string 82unbox(b2); // string 83unbox(b3); // InfBox<string> 84unbox({ value: { value: { value: { value: { value: { value: 5 }}}}}}); // number 85unbox(b4); // { value: { value: typeof b4 }} 86unbox({ value: { value: { get value() { return this; } }}}); // { readonly value: ... } 87 88// Inference from nested instantiations of same generic types 89 90type Box1<T> = { value: T }; 91type Box2<T> = { value: T }; 92 93declare function foo<T>(x: Box1<Box1<T>>): T; 94 95declare let z: Box2<Box2<string>>; 96 97foo(z); // unknown, but ideally would be string (requires unique recursion ID for each type reference) 98 99// Intersect tuple element types 100 101type Intersect<U extends any[], R = unknown> = U extends [infer H, ...infer T] ? Intersect<T, R & H> : R; 102 103type QQ = Intersect<[string[], number[], 7]>; 104 105// Infer between structurally identical recursive conditional types 106 107type Unpack1<T> = T extends (infer U)[] ? Unpack1<U> : T; 108type Unpack2<T> = T extends (infer U)[] ? Unpack2<U> : T; 109 110function f20<T, U extends T>(x: Unpack1<T>, y: Unpack2<T>) { 111 x = y; 112 y = x; 113 f20(y, x); 114} 115 116type Grow1<T extends unknown[], N extends number> = T['length'] extends N ? T : Grow1<[number, ...T], N>; 117type Grow2<T extends unknown[], N extends number> = T['length'] extends N ? T : Grow2<[string, ...T], N>; 118 119function f21<T extends number>(x: Grow1<[], T>, y: Grow2<[], T>) { 120 f21(y, x); // Error 121} 122 123// Repros from #41756 124 125type ParseSuccess<R extends string> = { rest: R }; 126 127type ParseManyWhitespace<S extends string> = 128 S extends ` ${infer R0}` ? 129 ParseManyWhitespace<R0> extends ParseSuccess<infer R1> ? ParseSuccess<R1> : null : 130 ParseSuccess<S>; 131 132type TP1 = ParseManyWhitespace<" foo">; 133 134type ParseManyWhitespace2<S extends string> = 135 S extends ` ${infer R0}` ? 136 Helper<ParseManyWhitespace2<R0>> : 137 ParseSuccess<S>; 138 139type Helper<T> = T extends ParseSuccess<infer R> ? ParseSuccess<R> : null 140 141type TP2 = ParseManyWhitespace2<" foo">; 142