
Build 10x products in minutes by chatting with AI - beyond just a prototype.
Topics
How do you initialize an array in TypeScript?
How do you initialise an empty array in TypeScript?
What is the difference between `Array<T>` and `T[]` in TypeScript?
Can a TypeScript array hold multiple types?
What is the difference between `push()` and the spread operator in TypeScript arrays?
How do you declare a readonly array in TypeScript?
How do you initialize a 2D array in TypeScript?
What is the best way to initialize a typed array for large datasets?
TypeScript arrays can be initialized using T[], Array<T>, new Array(), .fill(), as const, or readonly. Each method serves a different use case. This guide covers every approach with typed code examples, best practices, and TypeScript-specific patterns like readonly and tuples.
A TypeScript array is a statically typed, ordered collection that enforces a single element type or a defined union of types at compile time, catching mismatches before runtime. Knowing how to initialize an array in TypeScript correctly is foundational: it determines type safety, memory behavior, and how well TypeScript's type inference works across your codebase.
Five core methods to initialize an array in TypeScript, from simple literals to immutable readonly patterns.
| Method | Syntax | Mutability | Best For |
|---|---|---|---|
| Square brackets | let ids: number[] = [1, 2, 3] | Mutable | Most everyday arrays |
| Generic type | let ids: Array<number> = [1, 2, 3] | Mutable | Complex or union types |
| Array constructor | new Array("a", "b", "c") | Mutable | Dynamic initialization |
| fill() | new Array(5).fill(0) | Mutable | Fixed-length prefilled arrays |
| Spread operator | [...arr1, ...arr2] | New array | Merging two arrays |
| as const | ["dev", "prod"] as const | Readonly | Literal type inference |
| readonly | readonly string[] | Readonly | Immutable typed arrays |
An array in TypeScript is a collection of values of the same data type stored under a single variable. The elements of an array can be accessed using their index, starting from zero.
TypeScript's static typing system ensures that every element in a typed array conforms to the declared type, catching errors at compile time rather than runtime. As noted in the TypeScript Handbook , T[] and Array<T> are functionally identical; the choice between them is purely stylistic.
TypeScript provides multiple ways to declare and initialize an array:
[] (Array literal)Array<T>Each method has its advantages depending on the use case. TypeScript is now used by 78% of JavaScript developers , making typed array patterns a must-know skill.
Decision flowchart: choose the right TypeScript array initialization method based on mutability and data availability.
[] (Simplest Form)This is the most commonly used approach for array declaration and initialization. The square bracket syntax is concise, readable, and works seamlessly with TypeScript's type inference.
1let userIds: number[] = [101, 202, 303]; 2let productNames: string[] = ["Keyboard", "Monitor", "Headset"];
TypeScript enforces these types at compile time, preventing accidental type mismatches.
Another way to create an array is by using the array constructor. This approach is useful when you need to initialize an array dynamically or when the size is determined at runtime.
1let statusCodes = new Array("200", "404", "500"); 2console.log(statusCodes);
TypeScript will infer the type as string[] based on the provided elements. This method initializes a new array and assigns values immediately.
Array<T>The generic array type provides type safety and flexibility, especially when working with complex or union types.
1let apiResponse: Array<number | string> = [200, "OK", 404, "Not Found"]; 2console.log(apiResponse);
The Array<T> notation is often preferred in codebases that use complex generic types for consistency.
If an array should start with predefined values, TypeScript allows setting static values using the fill() method combined with the Array constructor.
1let scoreBoard: number[] = new Array(5).fill(0); 2console.log(scoreBoard); // Output: [0, 0, 0, 0, 0]
This pattern is commonly used when you need a fixed-length array pre-populated with a placeholder value. It pre-allocates memory and avoids repeated push() operations.
To access values from an array, use index notation. TypeScript's type system ensures that the accessed element matches the declared array type.
1let cartItemIds = [1001, 1002, 1003, 1004, 1005]; 2console.log(cartItemIds[0]); // First element: 1001 3console.log(cartItemIds[cartItemIds.length - 1]); // Last element: 1005
TypeScript also supports Array.prototype.at() (introduced in TypeScript 4.6 / ES2022), which accepts negative indices:
1console.log(cartItemIds.at(-1)); // Last element: 1005 — TS 4.6+ / ES2022
TypeScript will flag out-of-bounds access patterns when using strict mode with noUncheckedIndexedAccess, helping you avoid runtime errors.
To add elements, use the push() method. This appends one or more elements to the end of the array and returns the new length.
1let userList = ["Alice", "Bob"]; 2userList.push("Charlie"); 3console.log(userList); // ["Alice", "Bob", "Charlie"]
TypeScript ensures that only values matching the array's declared type can be pushed, catching type errors at compile time.
To remove elements, use pop() or shift(). These methods mutate the original array and return the removed element.
1let orderQueue = [1001, 1002, 1003, 1004]; 2orderQueue.pop(); // Removes last element (1004) 3orderQueue.shift(); // Removes first element (1001) 4console.log(orderQueue); // [1002, 1003]
These methods adjust the new length of the array dynamically. TypeScript infers the return type of pop() and shift() as the array's element type or undefined.
| Method | Removes From | Mutates Original | Returns |
|---|---|---|---|
push() | Adds to end | Yes | New length |
pop() | End | Yes | Removed element or undefined |
shift() | Start | Yes | Removed element or undefined |
unshift() | Adds to start | Yes | New length |
Spread [...arr] | Copies all | No | New array |
concat() | Merges | No | New array |

The four most-used TypeScript array manipulation methods, each serving a distinct transformation purpose.
TypeScript provides several built-in array methods that are fully typed, meaning TypeScript infers the return types automatically.
map()The map() function is useful for transforming an array. It returns a new array without mutating the original.
1let userScores = [85, 92, 78]; 2let grade = userScores.map(score => score >= 90 ? "A" : "B"); 3console.log(grade); // Output: ["B", "A", "B"]
filter()To extract specific array elements, use filter(). It returns a new array containing only elements that satisfy the provided condition.
1let inventoryLevels = [10, 0, 45, 0, 22]; 2let inStock = inventoryLevels.filter(qty => qty > 0); 3console.log(inStock); // Output: [10, 45, 22]
reduce()The reduce() function helps in aggregation. It processes each element and accumulates a single result.
1let orderAmounts = [120, 85, 200, 45]; 2let totalRevenue = orderAmounts.reduce((acc, amount) => acc + amount, 0); 3console.log(totalRevenue); // Output: 450
Typed array methods like these are central to building full-stack apps with AI prompts, where structured data handling drives the entire application layer.
The spread operator helps merge two arrays into a new array without mutating the originals.
1let premiumUsers = [1, 2, 3]; 2let freeUsers = [4, 5, 6]; 3 4let allUsers = [...premiumUsers, ...freeUsers]; 5console.log(allUsers); // [1, 2, 3, 4, 5, 6]
Another way to merge arrays is by using concat(). Like the spread operator, it returns a new array and does not mutate the originals.
1let combined = premiumUsers.concat(freeUsers); 2console.log(combined); // [1, 2, 3, 4, 5, 6]
When to use which: The spread operator is more flexible (you can insert elements between arrays), while concat() is slightly more readable when chaining multiple arrays. Understanding these patterns is essential when building scalable project structures for modern applications.
slice()To extract elements from an array, use slice(). It returns a shallow copy of a portion of the array without modifying the original.
1let transactionIds = [1001, 1002, 1003, 1004, 1005]; 2let recentTransactions = transactionIds.slice(1, 4); 3console.log(recentTransactions); // Output: [1002, 1003, 1004]
1let pageViews = [100, 200, 300]; 2console.log(pageViews[0]); // First element: 100 3console.log(pageViews.at(-1)); // Last element: 300 (ES2022 / TS 4.6+) 4console.log(pageViews[pageViews.length - 1]); // Last element (all TS versions)
readonly arrays block all mutating methods at compile time, while mutable arrays allow full modification.
These patterns are among the most searched TypeScript array topics and are critical for writing expert-level TypeScript code.
A readonly array prevents mutation after initialization. TypeScript will raise a compile-time error if you attempt to call push(), pop(), or any mutating method.
1let allowedRoles: readonly string[] = ["admin", "editor", "viewer"]; 2// allowedRoles.push("guest"); // Error: Property 'push' does not exist on type 'readonly string[]'
Use readonly when you want to enforce immutability in function parameters or module-level constants.
The as const assertion creates a ReadonlyArray with narrowed literal types rather than a broad string[] or number[].
1const environments = ["dev", "staging", "prod"] as const; 2// Type: readonly ["dev", "staging", "prod"] 3// environments[0] is typed as "dev", not string
This is especially powerful when used with union types: type Env = typeof environments[number] produces "dev" | "staging" | "prod".

As const narrows to exact literal values, readonly enforces immutability. Both serve different compile-time guarantees.
A tuple is a fixed-length typed array where each position has a specific type. Unlike regular arrays, tuples enforce both the number of elements and the type at each index.
1let userRecord: [number, string, boolean] = [1, "Alice", true]; 2// userRecord[0] is number, userRecord[1] is string, userRecord[2] is boolean
Tuples are ideal for representing structured data like API response pairs, coordinates, or function return values where order and type both matter. These patterns are especially relevant when generating authentication systems with AI , where typed return values prevent silent failures.
Using toString() or join(), an array can be converted into a string representation. This is useful for display, logging, or serialization purposes.
1let categories = ["Electronics", "Clothing", "Books"]; 2console.log(categories.toString()); // Output: Electronics,Clothing,Books 3console.log(categories.join(" | ")); // Output: Electronics | Clothing | Books
To convert an array into a localized string, use toLocaleString(). This is particularly useful when working with dates or numbers that need locale-aware formatting.
1let timestamps = [new Date()]; 2console.log(timestamps.toLocaleString());
TypeScript's growth is driven by compile-time safety; typed arrays are a core reason developers adopt it.
TypeScript's typed array system is a primary driver of its adoption. Teams that enforce typed arrays report fewer runtime errors, faster onboarding, and cleaner API contracts across their codebases.
Understanding typed array initialization is foundational whether you are building a REST API, a Next.js frontend, or a Flutter mobile app. For developers looking to go from TypeScript knowledge to shipped product, Rocket.new generates production-ready Next.js web apps and Flutter mobile apps with TypeScript configured out of the box.
Understanding how to initialize an array in TypeScript helps developers write cleaner and more maintainable code. Choosing the right approach, whether it is a simple T[] literal, a readonly immutable array, an as const assertion for literal types, or a tuple for positional typing, makes it easier to manage data, improve readability, and optimize performance.
TypeScript offers multiple ways to create and modify arrays while ensuring type safety. Whether working with numbers, strings, or custom objects, these methods provide the flexibility needed for different use cases.
The combination of static typing, powerful built-in array methods, and flexible initialization patterns makes TypeScript one of the strongest choices for modern application development.