Language
日本語
English

Caution

JavaScript is disabled in your browser.
This site uses JavaScript for features such as search.
For the best experience, please enable JavaScript before browsing this site.

  1. Home
  2. TypeScript Dictionary
  3. Recursive Types

Recursive Types

Since: TypeScript 3.7(2019)

This page covers advanced usage.

A recursive type is a type that references itself within its own definition. It is used to represent data of arbitrary depth, such as nested objects, tree structures, and JSON.

Syntax

type TreeNode = {
  value: number;
  children?: TreeNode[]; // References itself
};

Sample Code

type NestedObject = {
  [key: string]: string | number | NestedObject;
};

const data: NestedObject = {
  name: 'Kogami Shinya',
  age: 28,
  address: {
    city: 'Tokyo',
    zip: '100-0000',
    area: {
      ward: 'Chiyoda',
    },
  },
};

// Type representing a JSON value
type JSONValue =
  | string
  | number
  | boolean
  | null
  | JSONValue[]
  | { [key: string]: JSONValue };

const json: JSONValue = {
  title: 'TypeScript',
  version: 5,
  stable: true,
  tags: ['lang', 'typed'],
  meta: { author: 'Microsoft' },
};

// Tree structure
type TreeNode<T> = {
  value: T;
  children?: TreeNode<T>[];
};

const tree: TreeNode<string> = {
  value: 'root',
  children: [
    { value: 'child1' },
    {
      value: 'child2',
      children: [{ value: 'grandchild' }],
    },
  ],
};

// Recursive utility type: DeepReadonly
type DeepReadonly<T> = {
  readonly [K in keyof T]: T[K] extends object ? DeepReadonly<T[K]> : T[K];
};

Overview

TypeScript supports recursive type aliases (using type) since TypeScript 3.7. Before that, interfaces were required for recursive types, but now type aliases can directly reference themselves as well.

Recursive types let you accurately represent data structures of arbitrary depth. However, deeply nested type recursion can affect compiler performance. You can also combine recursive types with mapped types to create recursive utility types such as DeepReadonly and DeepPartial.

When using recursive types with recursive functions, narrow the type at each node using a typeof guard or an in operator guard as you traverse the structure.

If you find any errors or copyright issues, please .