Working with Arrays of Objects in TypeScript
Master arrays of objects in TypeScript. Learn to type collections of interfaces, iterate safely, and keep your task data structures predictable and error-free.

Previously in this course, we explored Defining Object Shapes with Interfaces and Typing Function Parameters in TypeScript. Now that you can describe a single task, it's time to manage groups of them by working with arrays of objects.
In real-world applications, you rarely deal with single items in isolation. APIs usually return lists, and your UI components need to render collections. Typing these collections correctly is the difference between a resilient application and one that crashes when an array is empty or malformed.
Defining Arrays of Interfaces
In JavaScript, an array is a flexible container. In TypeScript, we want to enforce that every item inside that container conforms to a specific shape. If we have a Task interface, we define an array of these objects by appending [] to the interface name.
TYPESCRIPTinterface Task { id: number; title: string; isCompleted: boolean; } // Defining a collection of tasks const tasks: Task[] = [ { id: 1, title: "Learn TypeScript Arrays", isCompleted: false }, { id: 2, title: "Build the API client", isCompleted: true } ];
By using Task[], TypeScript ensures that any object you push into this array—or any item you access from it—must satisfy the Task interface. If you try to add an object missing the id property, the compiler will stop you immediately.
Iterating Over Typed Arrays

Once you have a typed array, you need to iterate over it. Because the compiler knows the structure of each element, your IDE's autocomplete will suggest properties like .title or .isCompleted inside your loops.
When using methods like .map(), .filter(), or .forEach(), TypeScript automatically infers the type of the current element.
TYPESCRIPT// Iterating safely tasks.forEach((task) => { // TypeScript knows CE9178">'task' is of type Task console.log(CE9178">`Task: ${task.title.toUpperCase()}`); });
This is significantly safer than standard JavaScript, where you might accidentally misspell a property name or assume an object exists when it doesn't.
Accessing Array Elements Safely
A common source of runtime bugs is accessing an array index that doesn't exist. If you try to access tasks[5] in an array of only two items, JavaScript returns undefined. TypeScript, depending on your configuration, might warn you, but you should handle this explicitly.
To access elements safely, always verify the existence of the element or use optional chaining if you aren't certain the index is populated.
TYPESCRIPTconst firstTask = tasks[0]; // Type is Task // Accessing an potentially empty index const eleventhTask = tasks[10]; // Safe access: TypeScript forces you to consider the CE9178">'undefined' case if (eleventhTask) { console.log(eleventhTask.title); } else { console.log("Task not found."); }
Hands-on Exercise: Building the Task List
In our ongoing task API client project, let's implement a function that processes a list of tasks.
- Create an interface named
Taskwithid,title, andisCompleted. - Define an array named
myTasksinitialized with at least twoTaskobjects. - Write a function called
printTaskTitlesthat acceptsTask[]as a parameter and logs each title.
TYPESCRIPTinterface Task { id: number; title: string; isCompleted: boolean; } const myTasks: Task[] = [ { id: 1, title: "Setup Project", isCompleted: true }, { id: 2, title: "Type the Arrays", isCompleted: false } ]; function printTaskTitles(tasks: Task[]): void { tasks.forEach(t => console.log(t.title)); } printTaskTitles(myTasks);
Common Pitfalls
- Forgetting the
[]: A common mistake is typing a variable asTaskinstead ofTask[]. If you try to call.map()on a single object, your code will crash at runtime. - The
any[]trap: Avoid usingany[]. It defeats the purpose of TypeScript by allowing any data type to enter your collection. Always strive for specific interfaces. - Assuming length: Never assume an API returns an array. If your data comes from an external source, it might be
nullorundefined. Always check if your variable is an array before iterating.
FAQ
Q: Can I use Array<Task> instead of Task[]?
A: Yes. Both are functionally equivalent. Task[] is more concise and commonly preferred by the community, but Array<Task> is perfectly valid.
Q: How do I handle arrays that might be empty?
A: TypeScript doesn't treat empty arrays differently; they are still of type Task[]. Your code should simply check for the existence of elements inside the array before rendering them, usually through your framework's conditional rendering or a standard if check.
Recap

Working with collections requires a clear contract. By using Task[] (or Array<Task>), you provide TypeScript the metadata needed to prevent property access errors during iteration. Always prioritize explicit typing over any to keep your task client maintainable.
Up next: We will dive into Understanding Void and Undefined to clarify how to handle functions that don't return values and optional object properties.
Work with me

Next.js Full-Stack Web App Development
A fast, SEO-ready full-stack web app built with Next.js 16 — from idea to deployed product, by an engineer who ships to production.

React & Next.js Dashboard / Admin UI Development
A clean, data-rich dashboard UI in React or Next.js — charts, tables, and real-time data that your users will actually enjoy using.


