// @strict: true // @declaration: true // @target: esnext // Awaiting promises type Awaited = T extends null | undefined ? T : T extends PromiseLike ? Awaited : T; type MyPromise = { then(f: ((value: T) => U | PromiseLike) | null | undefined): MyPromise; } type InfinitePromise = Promise>; type P0 = Awaited | null> | undefined>>; type P1 = Awaited; type P2 = Awaited>; // Error function f11(tx: T, ta: Awaited, ux: U, ua: Awaited) { ta = ua; ua = ta; // Error ta = tx; // Error tx = ta; // Error } // Flattening arrays type Flatten = T extends unknown[] ? _Flatten[] : readonly _Flatten[]; type _Flatten = T extends readonly (infer U)[] ? _Flatten : T; type InfiniteArray = InfiniteArray[]; type B0 = Flatten; type B1 = Flatten; type B2 = Flatten>; type B3 = B2[0]; // Error // Repeating tuples type TupleOf = N extends N ? number extends N ? T[] : _TupleOf : never; type _TupleOf = R['length'] extends N ? R : _TupleOf; type TT0 = TupleOf; type TT1 = TupleOf; type TT2 = TupleOf; type TT3 = TupleOf; type TT4 = TupleOf; // Depth error function f22(tn: TupleOf, tm: TupleOf) { tn = tm; tm = tn; } declare function f23(t: TupleOf): T; f23(['a', 'b', 'c']); // string // Inference to recursive type interface Box { value: T }; type RecBox = T | Box>; type InfBox = Box>; declare function unbox(box: RecBox): T type T1 = Box; type T2 = Box; type T3 = Box; type T4 = Box; type T5 = Box; type T6 = Box; declare let b1: Box>>>>>; declare let b2: T6; declare let b3: InfBox; declare let b4: { value: { value: { value: typeof b4 }}}; unbox(b1); // string unbox(b2); // string unbox(b3); // InfBox unbox({ value: { value: { value: { value: { value: { value: 5 }}}}}}); // number unbox(b4); // { value: { value: typeof b4 }} unbox({ value: { value: { get value() { return this; } }}}); // { readonly value: ... } // Inference from nested instantiations of same generic types type Box1 = { value: T }; type Box2 = { value: T }; declare function foo(x: Box1>): T; declare let z: Box2>; foo(z); // unknown, but ideally would be string (requires unique recursion ID for each type reference) // Intersect tuple element types type Intersect = U extends [infer H, ...infer T] ? Intersect : R; type QQ = Intersect<[string[], number[], 7]>; // Infer between structurally identical recursive conditional types type Unpack1 = T extends (infer U)[] ? Unpack1 : T; type Unpack2 = T extends (infer U)[] ? Unpack2 : T; function f20(x: Unpack1, y: Unpack2) { x = y; y = x; f20(y, x); } type Grow1 = T['length'] extends N ? T : Grow1<[number, ...T], N>; type Grow2 = T['length'] extends N ? T : Grow2<[string, ...T], N>; function f21(x: Grow1<[], T>, y: Grow2<[], T>) { f21(y, x); // Error }