How to Create a Strongly Typed Array of Arrays in TypeScript: Syntax and Examples

You can declare a strongly typed array of arrays in TypeScript using either generic syntax Array<Array<T>> or shorthand syntax T[], nesting the type parameters for each dimension, with both styles defined in the TypeScript standard library files like src/lib/es2023.array.d.ts.

TypeScript provides two equivalent syntaxes for declaring array types that allow you to create strongly typed nested data structures. According to the microsoft/TypeScript source code, these type declarations are implemented in the core library definition files that the compiler automatically includes based on your tsconfig.json target.

Understanding TypeScript Array Type Syntax

TypeScript implements array types through two interchangeable forms defined in the standard library. In src/lib/es2023.array.d.ts, the generic interface is declared as:

interface Array<T> { … }

This generic form Array<T> accepts a type parameter representing the element type. The shorthand form T[] provides identical functionality with more concise syntax. Both compile to the same JavaScript at runtime because TypeScript erases type information during compilation.

Declaring Nested Arrays in TypeScript

To create a strongly typed array of arrays, you nest the type parameters or shorthand brackets for each additional dimension. The following table illustrates the TypeScript type of array syntax for nested arrays:

Desired Shape Generic Syntax Shorthand Syntax
2‑dimensional array of numbers Array<Array<number>> number[][]
3‑dimensional array of strings Array<Array<Array<string>>> string[][][]
2‑D array of custom objects Array<Array<User>> User[][]

The generic form proves especially useful when the inner type is itself a complex generic, such as Array<Array<Promise<Result>>>, while the shorthand form offers brevity for primitive types.

Readonly Nested Arrays for Immutability

When you need immutability guarantees, TypeScript provides ReadonlyArray<T> and the readonly modifier. These prevent mutation of the array itself and, when nested, of inner arrays as well.

// Readonly 2-D array using generic syntax
const frozenMatrix: ReadonlyArray<ReadonlyArray<number>> = [
  [1, 2],
  [3, 4]
];

// Readonly 2-D array using shorthand syntax
const frozenGrid: readonly boolean[][] = [
  [true, false],
  [false, true]
];

Attempting to modify a readonly nested array results in a compile-time error, ensuring type safety across complex data structures.

Source Code Implementation

The TypeScript compiler implements these array types in the standard library definition files located in src/lib/. Key files include:

These files are part of the TypeScript standard library that the compiler automatically includes based on the target option in tsconfig.json. The generic interface pattern allows TypeScript to provide strongly typed array methods like map(), filter(), and reduce() with full type inference.

Practical Code Examples

The following examples demonstrate how to create and manipulate strongly typed nested arrays using both syntax styles:

// 2-D numeric matrix (mutable)
let matrix: number[][] = [
  [1, 2, 3],
  [4, 5, 6],
];
matrix[1][2] = 9;           // ✅ OK
// matrix[1][2] = "nine";   // ❌ Type 'string' is not assignable to type 'number'

// Same matrix using generic syntax
let matrixGen: Array<Array<number>> = [
  [1, 2, 3],
  [4, 5, 6],
];

// 3-D array of strings (readonly)
const cube: readonly string[][][] = [
  [
    ["a1", "a2"],
    ["b1", "b2"],
  ],
];
// cube[0][1][0] = "new";   // ❌ Error – readonly

// Nested generic with a complex inner type
type ApiResult = Promise<{ ok: boolean }>;
let pendingCalls: Array<Array<ApiResult>> = [
  [fetch('/a'), fetch('/b')],
  [fetch('/c')],
];

Summary

  • TypeScript provides two equivalent syntaxes for strongly typed arrays: generic (Array<T>) and shorthand (T[]).
  • To create a strongly typed array of arrays, nest the type parameters: Array<Array<T>> or T[][] for two dimensions, adding additional nesting for deeper structures.
  • Use ReadonlyArray<T> or the readonly modifier to create immutable nested arrays that prevent compile-time mutation errors.
  • These type definitions reside in the TypeScript standard library files such as src/lib/es2023.array.d.ts and are automatically included by the compiler based on your tsconfig.json target.

Frequently Asked Questions

What is the difference between Array and T[] in TypeScript?

There is no functional difference between Array<T> and T[]; they are interchangeable syntaxes for the same type system construct. The generic Array<T> form is defined in src/lib/es2023.array.d.ts and is useful when the inner type is complex or when using utility types. The shorthand T[] is more concise and commonly used for primitive types like number[] or string[].

How do I declare a readonly nested array in TypeScript?

You can declare a readonly nested array using either ReadonlyArray<ReadonlyArray<T>> for full immutability of all levels, or readonly T[][] which makes the outer array readonly but requires additional readonly modifiers for inner arrays if needed. According to the TypeScript source in src/lib/es2023.array.d.ts, ReadonlyArray<T> prevents push, pop, and index assignment operations at compile time.

Can I mix generic and shorthand syntax for nested arrays?

Yes, you can mix generic and shorthand syntax when declaring nested arrays, though consistency improves readability. For example, Array<number[]> is valid and equivalent to Array<Array<number>> or number[][]. The TypeScript compiler normalizes these forms during type checking, as they all reference the same underlying Array<T> interface defined in the standard library files like src/lib/es5.d.ts.

Where are TypeScript array types defined in the source code?

TypeScript array types are defined in the standard library declaration files located in the src/lib/ directory of the microsoft/TypeScript repository. The primary definitions reside in src/lib/es2023.array.d.ts for modern ECMAScript targets, with fallbacks in src/lib/es2022.array.d.ts and src/lib/es5.d.ts for older compilation targets. These files declare the generic interface Array<T> and interface ReadonlyArray<T> that power all array type checking in the compiler.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →