Bird
Raised Fist0
Typescriptprogramming~20 mins

Recursive generic types in Typescript - Practice Problems & Coding Challenges

Choose your learning style10 modes available
Challenge - 5 Problems
🎖️
Recursive Generic Types Master
Get all challenges correct to earn this badge!
Test your skills under time pressure!
❓ Predict Output
intermediate
2:00remaining
Output of a recursive generic type with nested arrays
What is the type of NestedArray<number> when used as NestedArray<number> = [1, [2, [3]]]?
Typescript
type NestedArray<T> = T | NestedArray<T>[];

const example: NestedArray<number> = [1, [2, [3]]];
A"example" must be an array of arrays of numbers with exactly 3 levels
B"example" can be a number or an array of numbers nested any depth
C"example" can only be a single number, not arrays
D"example" must be a flat array of numbers only
Attempts:
2 left
💡 Hint
Think about how the recursive type allows nesting arrays inside arrays.
❓ Predict Output
intermediate
2:00remaining
Output of recursive generic type with object nodes
Given the type below, what is the type of Tree<string>?
Typescript
type Tree<T> = {
  value: T;
  children?: Tree<T>[];
};

const example: Tree<string> = {
  value: "root",
  children: [
    { value: "child1" },
    { value: "child2", children: [{ value: "grandchild" }] }
  ]
};
A"example" is an object with a value of type string and optional children which are arrays of similar objects recursively
B"example" is a flat object with only a value string and no children allowed
C"example" must be an array of strings only
D"example" is a string or an array of strings
Attempts:
2 left
💡 Hint
Look at how the children property is defined recursively.
🔧 Debug
advanced
2:00remaining
Identify the error in recursive generic type definition
Which option contains a syntax error in the recursive generic type definition?
Typescript
type Recursive<T> = T | Recursive<T>[];
Atype Recursive<T> = T | Recursive<T>[];
Btype Recursive<T> = T | Recursive<T>;
Ctype Recursive<T> = T | Recursive<T>[] | null;
Dtype Recursive<T> = T | Recursive[];
Attempts:
2 left
💡 Hint
Check if the generic parameter is correctly used in the recursive reference.
❓ Predict Output
advanced
2:00remaining
Output of a mapped recursive generic type
What is the resulting type of DeepReadonly<{ a: { b: number } }> given the definition below?
Typescript
type DeepReadonly<T> = {
  readonly [P in keyof T]: T[P] extends object ? DeepReadonly<T[P]> : T[P];
};

type Example = DeepReadonly<{ a: { b: number } }>;

// What is the type of Example?
A{ readonly a: { readonly b: number } }
B{ a: { b: number } }
C{ readonly a: { b: number } }
D{ a: { readonly b: number } }
Attempts:
2 left
💡 Hint
The type recursively applies readonly to all nested properties.
🧠 Conceptual
expert
3:00remaining
Understanding recursive generic constraints
Consider the recursive generic type below. What constraint does it enforce on the type parameter T?
Typescript
type RecursiveConstraint<T extends { children?: T[] }> = T;
AT must be an array type
BT can be any type including primitives
CT must be an object type that optionally has a children property which is an array of T
DT must be a function type with children as parameters
Attempts:
2 left
💡 Hint
Look at the constraint after the extends keyword carefully.

Practice

(1/5)
1. What is the main purpose of using recursive generic types in TypeScript?
easy
A. To create simple flat types without any nesting
B. To automatically generate UI components
C. To enforce runtime type checking
D. To define types that refer to themselves for nested or hierarchical data

Solution

  1. Step 1: Understand recursive generic types

    Recursive generic types allow a type to refer to itself, which helps model nested or hierarchical data structures like trees or linked lists.
  2. Step 2: Compare options

    Options A, C, and D do not describe recursive generics correctly. Only To define types that refer to themselves for nested or hierarchical data correctly states their purpose.
  3. Final Answer:

    To define types that refer to themselves for nested or hierarchical data -> Option D
  4. Quick Check:

    Recursive generics = self-referential types [OK]
Hint: Recursive generics model nested data by referring to themselves [OK]
Common Mistakes:
  • Thinking recursive generics are for runtime checks
  • Confusing recursive generics with simple generics
  • Assuming recursive generics flatten data
2. Which of the following is the correct syntax to define a recursive generic type for a nested object with children of the same type?
easy
A. type Node<T> = { value: T; children: Node[] };
B. type Node<T> = { value: T; children?: Node<T>[] };
C. type Node<T> = { value: T; children: Node<T> };
D. type Node<T> = { value: T; children: T[] };

Solution

  1. Step 1: Analyze recursive generic syntax

    The type should refer to itself with the generic parameter and allow children to be an array of the same type or optional to avoid infinite recursion.
  2. Step 2: Check each option

    type Node<T> = { value: T; children?: Node<T>[] }; correctly defines children as optional array of Node<T>. type Node<T> = { value: T; children: Node[] }; misses generic parameter. type Node<T> = { value: T; children: Node<T> }; makes children a single Node, not array. type Node<T> = { value: T; children: T[] }; uses T[] which is incorrect.
  3. Final Answer:

    type Node<T> = { value: T; children?: Node<T>[] }; -> Option B
  4. Quick Check:

    Recursive generic with optional children array = type Node<T> = { value: T; children?: Node<T>[] }; [OK]
Hint: Use optional array of same generic type for recursive children [OK]
Common Mistakes:
  • Omitting generic parameter in recursive reference
  • Making children non-array when it should be array
  • Not making children optional causing infinite recursion
3. Given the following TypeScript code, what is the type of tree.children[0].children[0].value?
type TreeNode<T> = { value: T; children?: TreeNode<T>[] };
const tree: TreeNode<string> = {
  value: "root",
  children: [
    { value: "child1", children: [{ value: "grandchild1" }] },
    { value: "child2" }
  ]
};
medium
A. string
B. TreeNode<string>
C. string | undefined
D. TreeNode<string> | undefined

Solution

  1. Step 1: Understand the type definition

    TreeNode<T> has a value of type T. Here, T is string.
  2. Step 2: Trace the property access

    tree.children[0].children[0].value accesses the value of a nested node, which is a string as per the generic type.
  3. Final Answer:

    string -> Option A
  4. Quick Check:

    Nested node value type = string [OK]
Hint: Generic type T defines value type at all levels [OK]
Common Mistakes:
  • Confusing node type with value type
  • Assuming children or value can be undefined here
  • Mixing up generic parameter with node type
4. Identify the error in this recursive generic type definition:
type ListNode<T> = {
  value: T;
  next: ListNode<T>;
};
medium
A. 'value' should be optional
B. Generic parameter T is not used correctly
C. Missing optional property for 'next' causing infinite recursion
D. TypeScript does not support recursive types

Solution

  1. Step 1: Analyze the recursive type definition

    The next property refers to ListNode<T> without being optional, so it requires an infinite chain.
  2. Step 2: Identify the fix

    Making next optional (next?: ListNode<T>) provides a base case to stop recursion.
  3. Final Answer:

    Missing optional property for 'next' causing infinite recursion -> Option C
  4. Quick Check:

    Recursive types need optional base case [OK]
Hint: Make recursive property optional to avoid infinite recursion [OK]
Common Mistakes:
  • Forgetting to add '?' to recursive property
  • Thinking TypeScript disallows recursive types
  • Making unrelated properties optional
5. You want to create a recursive generic type NestedArray<T> that represents an array of elements of type T or arrays of NestedArray<T> (nested arrays). Which of the following definitions correctly models this?
hard
A. type NestedArray<T> = Array;
B. type NestedArray<T> = T | NestedArray<T>[];
C. type NestedArray<T> = Array<T> | NestedArray<T>;
D. type NestedArray<T> = T[] | NestedArray<T>;

Solution

  1. Step 1: Understand the nested array structure

    A nested array can be an array of elements of type T or arrays of nested arrays recursively.
  2. Step 2: Evaluate each option

    type NestedArray<T> = Array; correctly defines NestedArray<T> as an array whose elements are either T or NestedArray<T>. type NestedArray<T> = T | NestedArray<T>[]; is incorrect because it allows a single element T without array wrapper. Options C and D misuse union and array placement.
  3. Final Answer:

    type NestedArray<T> = Array<T | NestedArray<T>>; -> Option A
  4. Quick Check:

    Nested arrays = arrays of T or nested arrays [OK]
Hint: Use array of union of T or NestedArray<T> for nested arrays [OK]
Common Mistakes:
  • Allowing T alone without array wrapper
  • Incorrect union placement outside array
  • Confusing recursive generic with simple union
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard