Challenge 3: Write DeepAwaited — Possible Solution ==================================================================== type DeepAwaited = T extends Promise ? DeepAwaited : T; // --- Usage --- type A = DeepAwaited>; // number type B = DeepAwaited>>>; // string type C = DeepAwaited; // boolean (base case — not a Promise at all) // Demonstrating the recursion step by step for // DeepAwaited>>>: // // DeepAwaited>>> // -> extends Promise? yes, U = Promise> // -> recurse: DeepAwaited>> // -> extends Promise? yes, U = Promise // -> recurse: DeepAwaited> // -> extends Promise? yes, U = string // -> recurse: DeepAwaited // -> extends Promise? NO — base case, return string // // Each recursive step peels off exactly one layer of Promise<...> until // the type underneath is no longer a Promise at all. WHY THIS WORKS -------------- - The true branch calls DeepAwaited on itself — TypeScript's type checker supports this kind of self-recursion in conditional types, evaluating it much like a recursive function would at runtime, just entirely at compile time. - The false branch (`: T`) is the base case: once T is no longer a Promise, the recursion stops and the current T is returned as-is. - Without a base case that eventually stops matching `Promise`, a recursive conditional type like this would exceed TypeScript's recursion depth limit and produce a compiler error — the base case here is guaranteed to terminate because each step strictly unwraps one level of Promise, and a real type can only be nested so many Promises deep.