How to use TypeScript arrays effectively
Arrays are fundamental building blocks in TypeScript, letting you work with collections of data while maintaining type safety. In this guide, you'll learn array basics, explore common operations, and see how TypeScript's type system helps catch errors before runtime. We'll walk through practical examples that you can apply to your own code.
Declaring and Initializing Arrays in TypeScript
Setting up arrays in TypeScript is simple and can include type annotations for added safety. You can declare an array using the []
syntax or the Array
constructor. For example:
// Simple number array
let numbers: number[] = [1, 2, 3, 4, 5];
// Alternative syntax using Array<T>
let strings: Array<string> = ['apple', 'banana', 'orange'];
// Empty array with type inference
let inferredNumbers = [] as number[];
// Using the Array constructor (less common)
let zeros: number[] = new Array(3).fill(0);
You can also initialize arrays with complex objects, such as interfaces:
interface User {
name: string;
age: number;
}
const users: User[] = [
{ name: 'John Doe', age: 30 },
{ name: 'Jane Doe', age: 25 }
];
TypeScript will now catch errors if you try to add objects that don't match the User interface.
Using Array Methods in TypeScript
TypeScript retains all of JavaScript's built-in array methods while adding type safety. Let's explore some essential methods like TypeScript map
, filter
, and reduce
. When filtering data in TypeScript, you get compile-time typechecking for your conditions:
// Starting array
const numbers = [1, 2, 3, 4, 5];
// Transform elements with map
const doubled = numbers.map(num => num * 2); // type: number[]
// Select elements with filter
const evenNumbers = numbers.filter(num => num % 2 === 0); // type: number[]
// Calculate a single value with reduce
const sum = numbers.reduce((total, num) => total + num, 0); // type: number
// Check if any element matches a condition
const hasNegative = numbers.some(num => num < 0); // type: boolean
// Verify all elements match a condition
const allPositive = numbers.every(num => num > 0); // type: boolean
Ensuring Type Safety with Arrays in TypeScript
Type safety is important to avoid errors. TypeScript's type system helps catch common array operations that might fail at runtime
// TypeScript prevents mixing types in arrays
const mixedArray = [1, 'two', 3]; // type: (string | number)[]
// Type annotation ensures consistent data
interface Task {
id: number;
title: string;
completed: boolean;
}
const tasks: Task[] = [
{ id: 1, title: 'Learn TypeScript', completed: false },
{ id: 2, title: 'Build project', completed: true }
];
// TypeScript catches missing or incorrect properties
tasks.push({ id: 3, title: 'Test code' }); // Error: missing 'completed'
// Type narrowing with array methods
const completedTasks = tasks.filter((task): task is Task => task.completed);
When building applications with Convex, you can combine TypeScript's type checking with complex filters to ensure your data queries are type-safe.
Handling Arrays of Complex Objects in TypeScript
Working with arrays of complex objects in TypeScript requires careful attention to type safety and access. You can use interfaces to define the structure of these nested objects:
interface Address {
street: string;
city: string;
}
interface User {
name: string;
address: Address;
}
const users: User[] = [
{ name: 'John Doe', address: { street: '123 Main St', city: 'Anytown' } },
{ name: 'Jane Doe', address: { street: '456 Elm St', city: 'Othertown' } }
];
users.forEach((user) => {
console.log(user.address.city);
});
You can also use type assertions to ensure that complex objects are of a specific type:
const users: any[] = [
{ name: 'John Doe', age: 30 },
{ name: 'Jane Doe', age: 25 }
];
users.forEach((user) => {
const typedUser = user as User;
console.log(typedUser.name);
});
Your data structures can become quite complex when building real applications. Check out how touncover API generation secrets for handling sophisticated data patterns.
Iterating Over Arrays in TypeScript
TypeScript ensures type safety across different iteration methods. The foreach
method provides a clean way to execute code for each element:
interface Product {
name: string;
price: number;
inStock: boolean;
}
const products: Product[] = [
{ name: "Laptop", price: 999, inStock: true },
{ name: "Mouse", price: 29, inStock: false }
];
// forEach with type inference
products.forEach(product => {
if (product.inStock) {
console.log(`${product.name}: $${product.price}`);
}
});
// for...of when you need to use break or continue
for (const product of products) {
if (!product.inStock) continue;
// Process in-stock items
}
// Classic for loop for index access
for (let i = 0; i < products.length; i++) {
const product = products[i];
// Access both index and element
}
Check out more TypeScript examples and patterns for working with data in your applications.