Flatten and UnwrapPromise Utilities
Write types that unwrap nested generic structures.
Flatten and UnwrapPromise Utilities is a free TypeScript Academy lesson on CoddyKit — lesson 2 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the TypeScript Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.
The Flatten Problem
JavaScript arrays can be nested. A Flatten utility type recursively removes array wrappers from a type, returning the innermost element type.
type Flatten<T> = T extends (infer U)[] ? Flatten<U> : T;
type A = Flatten<number[][][]>; // number
type B = Flatten<string[]>; // stringNon-Recursive Flatten (One Level)
A single-level flatten mirrors Array.prototype.flat(1) — it unwraps exactly one level of nesting.
type FlatOnce<T> = T extends (infer U)[] ? U : T;
type A = FlatOnce<number[][]>; // number[]
type B = FlatOnce<string[]>; // stringRecursive Flatten
The recursive version mimics Array.prototype.flat(Infinity) by recursing until no more array wrappers remain.
type Flatten<T> = T extends (infer U)[] ? Flatten<U> : T;
type C = Flatten<boolean[][][]>; // booleanUnwrapPromise: One Level
Unwrap a single Promise layer using infer.
type UnwrapPromise<T> = T extends Promise<infer U> ? U : T;
type D = UnwrapPromise<Promise<string>>; // string
type E = UnwrapPromise<number>; // numberDeep UnwrapPromise
Recursively unwrap nested promises — equivalent to the built-in Awaited.
type DeepUnwrap<T> = T extends Promise<infer U> ? DeepUnwrap<U> : T;
type F = DeepUnwrap<Promise<Promise<number>>>; // numberCombining Flatten and UnwrapPromise
A combined type handles both promises and arrays, useful for async functions that return arrays.
type Simplify<T> =
T extends Promise<infer U> ? Simplify<U>
: T extends (infer V)[] ? Simplify<V>
: T;
type G = Simplify<Promise<string[][]>>; // stringBuilt-in Awaited<T>
TypeScript 4.5+ ships Awaited which recursively unwraps thenable types including non-Promise thenables.
type H = Awaited<Promise<Promise<string>>>; // string
// Also handles custom thenables with .then()Unwrapping Map Values
The same infer pattern extracts value types from Map.
type MapValue<T> = T extends Map<any, infer V> ? V : never;
type I = MapValue<Map<string, number[]>>; // number[]FlattenObject: Merging Nested Interfaces
A type-level object flattener merges nested object types — more complex but useful for deep config merging.
// This requires recursive mapped types + intersection spreading
// See the DeepPartial lesson for the base patternPractical Use: API Response Unwrapping
Unwrap nested API response wrappers to get the data type without manual type assertions.
type ApiData<T> = { data: T; status: number };
type ExtractData<T> = T extends ApiData<infer D> ? D : T;
type J = ExtractData<ApiData<User[]>>; // User[]Recap: Flatten and Unwrap
Flatten and UnwrapPromise use recursive conditional types with infer to peel away type wrappers. Use Awaited for promise unwrapping and write custom recursion for other structures.
Quick Check
What does Flatten return?
What You Learned
Flatten and UnwrapPromise are recursive conditional types that peel off generic wrappers. Combine them to simplify complex nested types, and use the built-in Awaited for promise chains.
Frequently asked questions
Is the “Flatten and UnwrapPromise Utilities” lesson free?
Yes — the full text of “Flatten and UnwrapPromise Utilities” is free to read here on the web, and the TypeScript Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the TypeScript Academy course, upgrade to CoddyKit PRO.
What will I learn in “Flatten and UnwrapPromise Utilities”?
Write types that unwrap nested generic structures. You practise TypeScript Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.
Do I need any experience to start TypeScript Academy?
No prior experience is required. TypeScript Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 2 of 4, so you can start here or from the beginning and move at your own pace.
How long does the “Flatten and UnwrapPromise Utilities” lesson take?
Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.
Can I write and run code in this TypeScript Academy lesson?
Yes. Every TypeScript Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.
All lessons in this course
- DeepPartial and DeepReadonly
- Flatten and UnwrapPromise Utilities
- TupleToUnion and UnionToIntersection
- Publishing a Type Utility Library