How to Initialize an Array in TypeScript

When I build a sales dashboard or a Node.js order-processing script, I often need an array before any data arrives. Maybe the API has not returned orders yet, or I need a clean list to collect validation errors while processing a CSV file.

That is where knowing how to initialize an array in TypeScript helps. TypeScript is JavaScript with static type checking, so it lets you define both the array and the kind of values it should contain.

This practical guide shows the common ways to initialize arrays in TypeScript, when each approach makes sense, and the mistakes I avoid in real projects.

What Does Initialize an Array Mean?

An array is an ordered collection of values. Initializing an array means creating it, with or without values, so your code can use it later.

For example, a sales-reporting tool may store customer names, order totals, or complete order records in separate arrays. TypeScript adds type safety, which means it checks that you only add valid data types to those arrays.

A string[] accepts strings. A number[] accepts numbers. An array of objects can accept only objects that match a defined interface.

If you are new to the language, this guide on why developers use TypeScript explains why type checking helps catch bugs earlier.

Initialize an Array in TypeScript With Values

The quickest way to initialize an array in TypeScript is to place values inside square brackets. Use this approach when you already know the values your application needs.

const salesRegions: string[] = ["New York", "Chicago", "Austin", "Seattle"];

console.log(salesRegions);
console.log(salesRegions[0]);

Sample output:

[ 'New York', 'Chicago', 'Austin', 'Seattle' ]
New York

I executed the above example code and added the screenshot below.

Initialize an Array in TypeScript

Here, string[] tells TypeScript that salesRegions must contain only strings. The square brackets create the array, and the values inside become its initial items.

This initialization does not copy or transform anything. It creates one new mutable array. You can add, remove, or update items later.

const monthlySales: number[] = [12500, 18750, 22100, 16400];

monthlySales.push(20350);

console.log(monthlySales);

Sample output:

[ 12500, 18750, 22100, 16400, 20350 ]

I executed the above example code and added the screenshot below.

How to Initialize an Array in TypeScript

The push() method changes the original array by adding an item at the end. This is a mutation, which means code directly changes an existing array.

For a broader look at working with values, see how to add elements to an array in TypeScript.

Initialize an Empty Array in TypeScript

In backend services and frontend apps, data often arrives later. For example, you may fetch orders from an API, read rows from a file, or collect selected products from a user interface.

Initialize an empty typed array when you know the item type but do not have the values yet.

const customerNames: string[] = [];

customerNames.push("Emma Johnson");
customerNames.push("Michael Brown");
customerNames.push("Olivia Davis");

console.log(customerNames);

Sample output:

[ 'Emma Johnson', 'Michael Brown', 'Olivia Davis' ]

The empty brackets create an empty array. The string[] annotation is important because it tells TypeScript what values will arrive later.

Without an explicit type, TypeScript may infer a less helpful type for an empty array, depending on your configuration. I recommend declaring the type whenever you initialize an empty array in application code.

You can also use the generic array syntax:

const supportTicketIds: Array<number> = [];

supportTicketIds.push(1012);
supportTicketIds.push(1013);
supportTicketIds.push(1014);

console.log(supportTicketIds);

Sample output:

[ 1012, 1013, 1014 ]

I executed the above example code and added the screenshot below.

Initialize an Array TypeScript

Array<number> means the same thing as number[]. I usually use number[] because it is shorter and easier to scan. However, Array<T> works well when nested generic types make the code easier to read.

For more empty-array examples, read how to declare and initialize empty arrays in TypeScript.

Initialize an Array With a Type Alias

A type alias gives a reusable name to a type. It works well when array items can contain more than one kind of value.

For example, a dashboard filter may include text labels and numeric IDs.

type FilterValue = string | number;

const reportFilters: FilterValue[] = ["West", 2026, "Completed", 45];

console.log(reportFilters);

Sample output:

[ 'West', 2026, 'Completed', 45 ]

This array accepts strings and numbers, but it rejects booleans, objects, and other values. That keeps the allowed values clear without using any.

Avoid any[] unless you truly have no reliable information about the incoming data. An any value disables useful checks and makes bugs harder to find. You can learn more in this guide to the TypeScript any type.

Initialize an Array of Objects in TypeScript

Real applications often initialize arrays of objects. A support-ticket dashboard may hold ticket records, while an inventory script may hold products.

Use an interface to define the required shape of every object in the array. An interface describes the properties an object must contain.

interface SalesOrder {
orderId: number;
customerName: string;
total: number;
status: "Pending" | "Completed";
}

const salesOrders: SalesOrder[] = [
{
orderId: 1001,
customerName: "Sophia Miller",
total: 245.75,
status: "Completed"
},
{
orderId: 1002,
customerName: "Daniel Wilson",
total: 128.5,
status: "Pending"
}
];

console.log(salesOrders);
console.log(salesOrders[0].customerName);

Sample output:

[
{
orderId: 1001,
customerName: 'Sophia Miller',
total: 245.75,
status: 'Completed'
},
{
orderId: 1002,
customerName: 'Daniel Wilson',
total: 128.5,
status: 'Pending'
}
]
Sophia Miller

The SalesOrder[] type ensures every item includes orderId, customerName, total, and status. It also limits status to "Pending" or "Completed".

This approach protects a reporting script from inconsistent data. For example, TypeScript flags "Complete" because it does not match the allowed status values.

interface SalesOrder {
orderId: number;
customerName: string;
total: number;
status: "Pending" | "Completed";
}

const salesOrders: SalesOrder[] = [];

salesOrders.push({
orderId: 1003,
customerName: "Liam Anderson",
total: 399.99,
status: "Completed"
});

console.log(salesOrders);

Sample output:

[
{
orderId: 1003,
customerName: 'Liam Anderson',
total: 399.99,
status: 'Completed'
}
]

The array starts empty, then receives a correctly typed object. This pattern works especially well when your program receives items one at a time from an API or file-processing task.

For a deeper example, see arrays of objects in TypeScript.

Initialize an Array With Default Values

Sometimes you need an array with a fixed number of slots. For example, a dashboard may track twelve monthly totals, or a warehouse script may need daily counters for a week.

Use Array.from() when you want a new value created for every array position.

const monthlyRevenue: number[] = Array.from({ length: 12 }, () => 0);

console.log(monthlyRevenue);
console.log(monthlyRevenue.length);

Sample output:

[
0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0
]
12

Array.from() creates an array with twelve positions. The callback returns 0 for each position. This creates a mutable number array that you can update later.

const monthlyRevenue: number[] = Array.from({ length: 12 }, () => 0);

monthlyRevenue[0] = 12500;
monthlyRevenue[1] = 18750;

console.log(monthlyRevenue);

Sample output:

[
12500, 18750, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0
]

This is useful when array positions have meaning. In this example, index 0 represents January and index 1 represents February.

Avoid Shared Object References

Do not use fill() with an object when you expect each item to stay independent. fill() inserts the same object reference in every position.

interface DailySales {
total: number;
}

const incorrectDailySales: DailySales[] = Array(3).fill({ total: 0 });

incorrectDailySales[0].total = 500;

console.log(incorrectDailySales);

Sample output:

[ { total: 500 }, { total: 500 }, { total: 500 } ]

Every array item changed because all three positions point to the same object.

Use Array.from() instead, so TypeScript creates a new object for each position.

interface DailySales {
total: number;
}

const dailySales: DailySales[] = Array.from(
{ length: 3 },
() => ({ total: 0 })
);

dailySales[0].total = 500;

console.log(dailySales);

Sample output:

[ { total: 500 }, { total: 0 }, { total: 0 } ]

Each callback run creates a separate object. Updating the first object does not affect the others.

Pro Tip: I have seen Array(10).fill({}) create confusing dashboard bugs because every row shares one object. I use Array.from() whenever I initialize an array of objects with default values.

Initialize a Readonly Array in TypeScript

A readonly array is an array that TypeScript prevents you from modifying. It works well for application constants, configuration lists, and input data that a function should only read.

Use readonly Type[] or ReadonlyArray<Type>.

const supportedRegions: readonly string[] = [
"New York",
"Chicago",
"Austin",
"Seattle"
];

console.log(supportedRegions);
console.log(supportedRegions.length);

Sample output:

[ 'New York', 'Chicago', 'Austin', 'Seattle' ]
4

You can read values, check the length, and loop through a readonly array. TypeScript does not allow push(), pop(), splice(), or direct index assignment.

const supportedRegions: ReadonlyArray<string> = [
"New York",
"Chicago",
"Austin"
];

const regionSummary = supportedRegions.join(" | ");

console.log(regionSummary);

Sample output:

New York | Chicago | Austin

join() does not change the original array. It returns a new string, so TypeScript allows it on a readonly array.

If you need a mutable copy, use spread syntax. Spread syntax copies items from one array into another array.

const supportedRegions: readonly string[] = [
"New York",
"Chicago",
"Austin"
];

const editableRegions: string[] = [...supportedRegions];

editableRegions.push("Seattle");

console.log(supportedRegions);
console.log(editableRegions);

Sample output:

[ 'New York', 'Chicago', 'Austin' ]
[ 'New York', 'Chicago', 'Austin', 'Seattle' ]

The original readonly array stays unchanged. The new editableRegions array is mutable.

You can also review readonly arrays in TypeScript for more practical patterns.

Initialize Arrays With a Generic Function

A generic function is a reusable function that works with many data types while preserving type safety. Use one when you need the same initialization logic for strings, numbers, objects, or any other type.

The following function creates an array of a specific size and uses a factory function to create each item.

function createArray<T>(length: number, createItem: (index: number) => T): T[] {
return Array.from({ length }, (_, index) => createItem(index));
}

const orderNumbers = createArray<number>(5, (index) => 1001 + index);
const teamMembers = createArray<string>(3, (index) => `Sales Rep ${index + 1}`);

console.log(orderNumbers);
console.log(teamMembers);

Sample output:

[ 1001, 1002, 1003, 1004, 1005 ]
[ 'Sales Rep 1', 'Sales Rep 2', 'Sales Rep 3' ]

<T> represents the type that the caller chooses. For orderNumbers, T is number. For teamMembers, T is string.

The function returns a new array every time. It does not mutate an existing array, which makes it easier to use safely in backend services and frontend components.

Here is the same generic function with typed sales records.

interface SalesTarget {
repName: string;
monthlyTarget: number;
}

function createArray<T>(length: number, createItem: (index: number) => T): T[] {
return Array.from({ length }, (_, index) => createItem(index));
}

const salesTargets = createArray<SalesTarget>(3, (index) => ({
repName: `Representative ${index + 1}`,
monthlyTarget: 25000
}));

console.log(salesTargets);

Sample output:

[
{ repName: 'Representative 1', monthlyTarget: 25000 },
{ repName: 'Representative 2', monthlyTarget: 25000 },
{ repName: 'Representative 3', monthlyTarget: 25000 }
]

Each item is a separate object because the factory callback creates a fresh object during every iteration. This pattern avoids the shared-reference problem from fill().

For related reusable patterns, see generic arrow functions in TypeScript.

Initialize a Two-Dimensional Array

A two-dimensional array is an array that contains other arrays. You may use one for a sales grid, seating layout, spreadsheet-like data, or matrix calculations.

This example creates a weekly sales table with three sales representatives and four weeks.

const weeklySales: number[][] = [
[1200, 1350, 1425, 1500],
[1100, 1450, 1380, 1600],
[1250, 1300, 1475, 1550]
];

console.log(weeklySales);
console.log(weeklySales[1][3]);

Sample output:

[
[ 1200, 1350, 1425, 1500 ],
[ 1100, 1450, 1380, 1600 ],
[ 1250, 1300, 1475, 1550 ]
]
1600

number[][] means every outer-array item must be a number[]. The expression weeklySales[1][3] reads the fourth week for the second representative.

When you need an empty grid with independent rows, use nested Array.from() calls.

const rows = 3;
const columns = 4;

const salesGrid: number[][] = Array.from(
{ length: rows },
() => Array.from({ length: columns }, () => 0)
);

salesGrid[0][1] = 250;

console.log(salesGrid);

Sample output:

[
[ 0, 250, 0, 0 ],
[ 0, 0, 0, 0 ],
[ 0, 0, 0, 0 ]
]

Each row is a different array. That matters because changing one row should never update every row.

Learn more about this structure in how to work with 2D arrays in TypeScript.

Things to Keep in Mind

  • Add explicit types to empty arrays: Use string[], number[], or a custom interface array instead of relying on unclear inference.
  • Avoid any[]: It removes useful type safety and allows invalid data to enter your application.
  • Use Array.from() for object defaults: It creates a separate object for each array position, unlike fill() with an object.
  • Remember mutation: Methods such as push(), pop(), splice(), and direct index assignment change the original array.
  • Use readonly arrays for fixed data: A readonly array prevents accidental changes to shared configuration and reference data.
  • Avoid unnecessary copies for large datasets: Spread syntax creates a new array, so use it when you need isolation rather than by default.

Frequently Asked Questions

How do I initialize an empty array in TypeScript?

Declare the value with an explicit array type and assign empty square brackets. For example, use const names: string[] = [];. You can then add only string values with methods such as push().

What is the best way to initialize an array in TypeScript?

Use array literals such as const names: string[] = ["Emma", "Noah"]; when you already have values. Use a typed empty array when values arrive later. Use Array.from() when you need a fixed-size array with calculated or default values.

How do I initialize an array of objects in TypeScript?

First, define an interface for the object shape. Then use that interface followed by [], such as const orders: SalesOrder[] = [];. TypeScript then checks every object that you add.

Should I use string[] or Array<string> in TypeScript?

Both forms mean the same thing and compile to JavaScript arrays. I usually use string[] for simple arrays because it is shorter. Array<string> can read better for more complex nested generic types.

Why does Array(3).fill({}) update every object?

fill() uses the same object reference in every position. When you update one object, every array item reflects that update. Use Array.from({ length: 3 }, () => ({})) to create separate objects.

Can I initialize a readonly array in TypeScript?

Yes. Use readonly string[] or ReadonlyArray<string>. TypeScript lets you read and loop through the values, but it blocks changes such as push() and splice().

Initializing arrays in TypeScript becomes simple once you match the syntax to your data. Use typed array literals for known values, typed empty arrays for data you will collect later, and Array.from() when you need safe default values or independent objects.

For most application code, I recommend clear types and Array.from() for generated data because both make your intent obvious. I hope you found this article helpful.

You May Also Like:

51 Python Programs

51 PYTHON PROGRAMS PDF FREE

Download a FREE PDF (112 Pages) Containing 51 Useful Python Programs.

pyython developer roadmap

Aspiring to be a Python developer?

Download a FREE PDF on how to become a Python developer.

Let’s be friends

Be the first to know about sales and special discounts.