Generate Recursive TypeScript Types from Self-Referencing JSON

Learn how to convert self-referencing JSON structures like trees, comments, and menus into recursive TypeScript interfaces.

Complex Types

Detailed Explanation

Recursive Structures in JSON

Many data models are inherently recursive: file systems, comment threads, org charts, and navigation menus all contain nodes that reference the same type.

Example JSON

{
  "id": 1,
  "name": "Root",
  "children": [
    {
      "id": 2,
      "name": "Child A",
      "children": [
        { "id": 4, "name": "Grandchild", "children": [] }
      ]
    },
    {
      "id": 3,
      "name": "Child B",
      "children": []
    }
  ]
}

Generated TypeScript

interface TreeNode {
  id: number;
  name: string;
  children: TreeNode[];
}

How Recursion Is Detected

The converter walks the JSON structure and compares the shape of nested objects to their parents. When it finds that a child object has the same set of keys and compatible value types as an ancestor, it generates a self-referencing interface instead of creating infinite nested types.

Comment Thread Example

{
  "id": 100,
  "author": "Alice",
  "text": "Great article!",
  "replies": [
    {
      "id": 101,
      "author": "Bob",
      "text": "Thanks!",
      "replies": []
    }
  ]
}
interface Comment {
  id: number;
  author: string;
  text: string;
  replies: Comment[];
}

Mutually Recursive Types

Sometimes two types reference each other:

interface Folder {
  name: string;
  files: File[];
  subfolders: Folder[];
}

interface File {
  name: string;
  size: number;
  parent: Folder;
}

TypeScript handles forward references between interfaces seamlessly, so declaration order does not matter.

Depth Safety

When consuming recursive types, always set a maximum depth for traversal or rendering to avoid stack overflows. The type itself imposes no depth limit — that is a runtime concern.

Use Case

You are building a comment system where each comment can have nested replies, and you need a single recursive type that models the entire thread at any depth.

Try It — JSON to TypeScript

Open full tool