TypeScript Loops
Loops are essential control structures in programming that allow you to execute a block of code multiple times. In TypeScript, loops operate just like in JavaScript but with the added benefit of type safety. Understanding loops is crucial for efficient programming, as they help automate repetitive tasks and process collections of data.
Introduction to Loops in TypeScript
When programming, you'll often encounter situations where you need to perform the same operation multiple times. Instead of writing the same code repeatedly, loops provide a way to repeat code execution with different values until a certain condition is met.
TypeScript supports several types of loops:
for
loopswhile
loopsdo-while
loopsfor...of
loops (for iterable objects)for...in
loops (for objects)
Let's explore each of these loop types with examples and use cases.
The for
Loop
The for
loop is one of the most common loops in TypeScript. It consists of three parts: initialization, condition, and increment/decrement.
Basic Syntax
for (initialization; condition; increment/decrement) {
// Code to be executed
}
Example: Counting from 1 to 5
for (let i: number = 1; i <= 5; i++) {
console.log(`Count: ${i}`);
}
Output:
Count: 1
Count: 2
Count: 3
Count: 4
Count: 5
In this example:
let i: number = 1
initializes a counter variablei <= 5
is the condition that must be true for the loop to continuei++
increments the counter after each iteration
Practical Example: Processing an Array
const fruits: string[] = ['Apple', 'Banana', 'Orange', 'Mango', 'Strawberry'];
const fruitBasket: string[] = [];
for (let i = 0; i < fruits.length; i++) {
fruitBasket.push(`Fresh ${fruits[i]}`);
console.log(`Added ${fruits[i]} to the basket`);
}
console.log('Basket contents:', fruitBasket);
Output:
Added Apple to the basket
Added Banana to the basket
Added Orange to the basket
Added Mango to the basket
Added Strawberry to the basket
Basket contents: [ 'Fresh Apple', 'Fresh Banana', 'Fresh Orange', 'Fresh Mango', 'Fresh Strawberry' ]
The while
Loop
The while
loop executes a block of code as long as a specified condition is true.
Basic Syntax
while (condition) {
// Code to be executed
}
Example: Counting Down from 5
let countdown: number = 5;
while (countdown > 0) {
console.log(`Countdown: ${countdown}`);
countdown--;
}
console.log('Blast off!');
Output:
Countdown: 5
Countdown: 4
Countdown: 3
Countdown: 2
Countdown: 1
Blast off!
Practical Example: Random Number Generation
let attempts: number = 0;
let foundTarget: boolean = false;
// Keep generating random numbers until we get one greater than 0.9
while (!foundTarget) {
attempts++;
const randomValue: number = Math.random();
console.log(`Attempt ${attempts}: Generated ${randomValue.toFixed(4)}`);
if (randomValue > 0.9) {
foundTarget = true;
console.log(`Success! Found value > 0.9 after ${attempts} attempts`);
}
// Safety check to avoid infinite loop during demonstration
if (attempts >= 10) break;
}
Output (will vary):
Attempt 1: Generated 0.2415
Attempt 2: Generated 0.6124
Attempt 3: Generated 0.1842
Attempt 4: Generated 0.9234
Success! Found value > 0.9 after 4 attempts
The do-while
Loop
The do-while
loop is similar to the while
loop, but it executes the code block at least once before checking the condition.
Basic Syntax
do {
// Code to be executed
} while (condition);
Example: Basic do-while
let count: number = 0;
do {
console.log(`Count is: ${count}`);
count++;
} while (count < 3);
Output:
Count is: 0
Count is: 1
Count is: 2
Practical Example: User Input Validation
Here's a pseudo-code example simulating user input validation:
function getUserInput(): string {
// In a real application, this would get input from the user
// Here we'll simulate with predefined values
const possibleInputs = ['invalid', 'invalid again', 'valid input'];
return possibleInputs[Math.floor(Math.random() * possibleInputs.length)];
}
let userInput: string;
let attempt: number = 1;
do {
console.log(`Attempt ${attempt}: Requesting valid input...`);
userInput = getUserInput();
console.log(`Received: "${userInput}"`);
if (userInput !== 'valid input') {
console.log('Invalid input, please try again');
attempt++;
}
// Prevent infinite loop in this simulation
if (attempt > 5) {
console.log('Too many attempts, breaking loop');
break;
}
} while (userInput !== 'valid input');
if (userInput === 'valid input') {
console.log('Successfully received valid input!');
}
Output (will vary):
Attempt 1: Requesting valid input...
Received: "invalid"
Invalid input, please try again
Attempt 2: Requesting valid input...
Received: "valid input"
Successfully received valid input!
The for...of
Loop
The for...of
loop iterates over iterable objects like arrays, strings, and other collections.
Basic Syntax
for (const element of iterable) {
// Code to be executed
}
Example: Iterating Through an Array
const colors: string[] = ['red', 'green', 'blue', 'yellow'];
for (const color of colors) {
console.log(`Color: ${color}`);
}
Output:
Color: red
Color: green
Color: blue
Color: yellow
Practical Example: Processing Data Objects
interface Product {
id: number;
name: string;
price: number;
}
const inventory: Product[] = [
{ id: 1, name: 'Laptop', price: 1200 },
{ id: 2, name: 'Phone', price: 800 },
{ id: 3, name: 'Tablet', price: 500 },
{ id: 4, name: 'Headphones', price: 150 }
];
let totalValue: number = 0;
for (const product of inventory) {
console.log(`${product.name}: $${product.price}`);
totalValue += product.price;
}
console.log(`Total inventory value: $${totalValue}`);
Output:
Laptop: $1200
Phone: $800
Tablet: $500
Headphones: $150
Total inventory value: $2650
The for...in
Loop
The for...in
loop iterates over all enumerable properties of an object.
Basic Syntax
for (const key in object) {
// Code to be executed
}
Example: Iterating Through Object Properties
const person = {
firstName: 'John',
lastName: 'Doe',
age: 30,
occupation: 'Developer'
};
for (const property in person) {
console.log(`${property}: ${person[property]}`);
}
Output:
firstName: John
lastName: Doe
age: 30
occupation: Developer
Practical Example: Dynamic Form Configuration
interface FormConfig {
[key: string]: {
type: string;
required: boolean;
label: string;
};
}
const userFormConfig: FormConfig = {
username: {
type: 'text',
required: true,
label: 'Username'
},
email: {
type: 'email',
required: true,
label: 'Email Address'
},
age: {
type: 'number',
required: false,
label: 'Age'
}
};
console.log('Form Field Configuration:');
for (const field in userFormConfig) {
const config = userFormConfig[field];
console.log(
`- ${config.label} (${field}): ` +
`Type: ${config.type}, ` +
`Required: ${config.required ? 'Yes' : 'No'}`
);
}
Output:
Form Field Configuration:
- Username (username): Type: text, Required: Yes
- Email Address (email): Type: email, Required: Yes
- Age (age): Type: number, Required: No
Loop Control Statements
TypeScript provides statements to control the behavior of loops:
break
Statement
The break
statement terminates the current loop and transfers control to the statement following the loop.
for (let i = 1; i <= 10; i++) {
if (i === 5) {
console.log('Breaking loop at i = 5');
break;
}
console.log(`Current value: ${i}`);
}
console.log('Loop completed');
Output:
Current value: 1
Current value: 2
Current value: 3
Current value: 4
Breaking loop at i = 5
Loop completed
continue
Statement
The continue
statement skips the current iteration and proceeds to the next iteration of the loop.
for (let i = 1; i <= 5; i++) {
if (i === 3) {
console.log('Skipping iteration at i = 3');
continue;
}
console.log(`Processing value: ${i}`);
}
console.log('Loop completed');
Output:
Processing value: 1
Processing value: 2
Skipping iteration at i = 3
Processing value: 4
Processing value: 5
Loop completed
Nested Loops
You can also nest loops within each other for more complex operations.
console.log('Multiplication Table:');
for (let i = 1; i <= 3; i++) {
let row = '';
for (let j = 1; j <= 3; j++) {
row += `${i * j}\t`;
}
console.log(row);
}
Output:
Multiplication Table:
1 2 3
2 4 6
3 6 9
Loop Performance Considerations
When working with loops, keep these performance considerations in mind:
- Loop optimization: Pre-calculate array lengths when possible
- Choose the right loop: Different loops perform better in different scenarios
- Avoid expensive operations inside loops
// Less optimal
const items: number[] = [1, 2, 3, 4, 5];
for (let i = 0; i < items.length; i++) {
// items.length is recalculated in each iteration
console.log(items[i]);
}
// More optimal
const optimizedItems: number[] = [1, 2, 3, 4, 5];
const len = optimizedItems.length;
for (let i = 0; i < len; i++) {
// Length is calculated once
console.log(optimizedItems[i]);
}
Real-World Applications
Data Processing Pipeline
interface DataRecord {
id: number;
value: string;
isValid: boolean;
}
// Sample data
const records: DataRecord[] = [
{ id: 1, value: 'First Record', isValid: true },
{ id: 2, value: 'Corrupted', isValid: false },
{ id: 3, value: 'Third Record', isValid: true },
{ id: 4, value: '', isValid: false },
{ id: 5, value: 'Fifth Record', isValid: true }
];
// Process records
const validRecords: DataRecord[] = [];
const invalidRecords: DataRecord[] = [];
for (const record of records) {
if (record.isValid && record.value.length > 0) {
// Process valid records
const processedRecord = {
...record,
value: record.value.toUpperCase()
};
validRecords.push(processedRecord);
console.log(`Processed valid record ${record.id}`);
} else {
// Collect invalid records for error reporting
invalidRecords.push(record);
console.log(`Skipped invalid record ${record.id}`);
}
}
console.log('\nProcessing Summary:');
console.log(`Total records: ${records.length}`);
console.log(`Valid records: ${validRecords.length}`);
console.log(`Invalid records: ${invalidRecords.length}`);
Output:
Processed valid record 1
Skipped invalid record 2
Processed valid record 3
Skipped invalid record 4
Processed valid record 5
Processing Summary:
Total records: 5
Valid records: 3
Invalid records: 2
Building a Dynamic UI Component
Here's an example of how loops might be used to create a dynamic UI component in a TypeScript-based front-end application:
interface MenuItem {
id: string;
label: string;
url: string;
children?: MenuItem[];
}
function generateMenu(items: MenuItem[]): string {
let menuHTML = '<ul class="menu">';
for (const item of items) {
menuHTML += `<li id="${item.id}">`;
menuHTML += `<a href="${item.url}">${item.label}</a>`;
// Handle nested menu items with recursion
if (item.children && item.children.length > 0) {
menuHTML += generateMenu(item.children);
}
menuHTML += '</li>';
}
menuHTML += '</ul>';
return menuHTML;
}
const menuStructure: MenuItem[] = [
{
id: 'home',
label: 'Home',
url: '/home'
},
{
id: 'products',
label: 'Products',
url: '/products',
children: [
{ id: 'electronics', label: 'Electronics', url: '/products/electronics' },
{ id: 'clothing', label: 'Clothing', url: '/products/clothing' }
]
},
{
id: 'about',
label: 'About Us',
url: '/about'
}
];
console.log(generateMenu(menuStructure));
Output:
<ul class="menu"><li id="home"><a href="/home">Home</a></li><li id="products"><a href="/products">Products</a><ul class="menu"><li id="electronics"><a href="/products/electronics">Electronics</a></li><li id="clothing"><a href="/products/clothing">Clothing</a></li></ul></li><li id="about"><a href="/about">About Us</a></li></ul>
Summary
Loops are essential programming constructs that allow you to:
- Execute code repeatedly based on conditions
- Process collections of data efficiently
- Automate repetitive tasks
- Implement complex algorithms
In TypeScript, you have several loop types at your disposal:
for
loops for known iteration countswhile
loops for condition-based iterationsdo-while
loops for at least one executionfor...of
loops for iterablesfor...in
loops for object properties
Each loop type has its ideal use cases, and mastering them will make your TypeScript code more efficient and readable.
Exercises
To practice what you've learned about TypeScript loops, try these exercises:
- Write a function that uses a loop to reverse a string
- Create a loop that filters an array of numbers to separate odd and even values
- Implement a nested loop to generate a pattern of asterisks forming a triangle
- Use a
for...of
loop to find the maximum value in an array of numbers - Create a function that uses loops to check if a string is a palindrome
Additional Resources
- TypeScript Official Documentation
- MDN Web Docs - Loops and iteration
- TypeScript Deep Dive - Iteration
- TypeScript Playground - Test your loop implementations online
Happy coding with TypeScript loops!
If you spot any mistakes on this website, please let me know at [email protected]. I’d greatly appreciate your feedback! :)