Control Flow in TypeScript

In this lesson, we'll explore how TypeScript handles program flow control through conditionals and loops. These are essential tools for writing programs that can make decisions and repeat actions.

If Statements

TypeScript uses the same conditional syntax as JavaScript, with added type safety:

const age: number = 18;

if (age >= 18) {
  console.log("You are an adult");
} else {
  console.log("You are a minor");
}

If-Else If-Else

Handle multiple conditions with else if:

const score: number = 85;

if (score >= 90) {
  console.log("Grade: A");
} else if (score >= 80) {
  console.log("Grade: B");
} else if (score >= 70) {
  console.log("Grade: C");
} else if (score >= 60) {
  console.log("Grade: D");
} else {
  console.log("Grade: F");
}

Ternary Operator

For simple conditions, use the ternary operator:

const temperature: number = 25;
const weather: string = temperature > 20 ? "warm" : "cold";

console.log(`It's ${weather} today`);

// Nested ternary (use sparingly for readability)
const category: string =
  temperature > 30 ? "hot" :
  temperature > 20 ? "warm" :
  temperature > 10 ? "cool" : "cold";

console.log(`Temperature category: ${category}`);

Switch Statements

Switch statements provide a clean way to handle multiple cases:

const day: number = 3;
let dayName: string;

switch (day) {
  case 1:
    dayName = "Monday";
    break;
  case 2:
    dayName = "Tuesday";
    break;
  case 3:
    dayName = "Wednesday";
    break;
  case 4:
    dayName = "Thursday";
    break;
  case 5:
    dayName = "Friday";
    break;
  case 6:
  case 7:
    dayName = "Weekend";
    break;
  default:
    dayName = "Invalid day";
}

console.log(`Day ${day} is ${dayName}`);

For Loops

Traditional For Loop

console.log("Counting to 5:");
for (let i = 1; i <= 5; i++) {
  console.log(i);
}

For-Of Loop

Iterate over array values:

const fruits: string[] = ["apple", "banana", "orange"];

console.log("Fruits:");
for (const fruit of fruits) {
  console.log(fruit);
}

For-In Loop

Iterate over object keys (use with caution on arrays):

const person = {
  name: "Alice",
  age: 30,
  city: "New York"
};

console.log("Person properties:");
for (const key in person) {
  console.log(`${key}: ${person[key as keyof typeof person]}`);
}

While Loops

Execute code while a condition is true:

let countdown: number = 5;

console.log("Countdown:");
while (countdown > 0) {
  console.log(countdown);
  countdown--;
}
console.log("Blastoff!");

Do-While Loops

Execute code at least once, then check the condition:

let attempts: number = 0;
const maxAttempts: number = 3;

do {
  attempts++;
  console.log(`Attempt ${attempts}`);
} while (attempts < maxAttempts);

console.log("Done!");

Break and Continue

Break

Exit a loop early:

console.log("Finding first number divisible by 7:");
for (let i = 1; i <= 20; i++) {
  if (i % 7 === 0) {
    console.log(`Found: ${i}`);
    break;
  }
}

Continue

Skip to the next iteration:

console.log("Odd numbers from 1 to 10:");
for (let i = 1; i <= 10; i++) {
  if (i % 2 === 0) {
    continue; // Skip even numbers
  }
  console.log(i);
}

Type Guards

TypeScript can narrow types within conditional blocks:

function processValue(value: string | number): void {
  if (typeof value === "string") {
    // TypeScript knows value is a string here
    console.log(`String length: ${value.length}`);
  } else {
    // TypeScript knows value is a number here
    console.log(`Number doubled: ${value * 2}`);
  }
}

processValue("Hello");
processValue(42);

Try It Yourself

Practice control flow in the playground below:

// If-else example
const temperature: number = 22;

if (temperature > 30) {
  console.log("It's hot outside!");
} else if (temperature > 20) {
  console.log("It's a pleasant day!");
} else {
  console.log("It's cold outside!");
}

// For loop example
console.log("\nMultiplication table for 5:");
for (let i = 1; i <= 10; i++) {
  console.log(`5 x ${i} = ${5 * i}`);
}

// For-of loop example
const colors: string[] = ["red", "green", "blue"];

console.log("\nColors:");
for (const color of colors) {
  console.log(color);
}

// While loop example
let number: number = 1;
console.log("\nPowers of 2 (up to 64):");
while (number <= 64) {
  console.log(number);
  number *= 2;
}

// Switch statement example
const month: number = 3;
let season: string;

switch (month) {
  case 12:
  case 1:
  case 2:
    season = "Winter";
    break;
  case 3:
  case 4:
  case 5:
    season = "Spring";
    break;
  case 6:
  case 7:
  case 8:
    season = "Summer";
    break;
  case 9:
  case 10:
  case 11:
    season = "Fall";
    break;
  default:
    season = "Unknown";
}

console.log(`\nMonth ${month} is in ${season}`);

// Break and continue example
console.log("\nNumbers from 1 to 10, skipping 5:");
for (let i = 1; i <= 10; i++) {
  if (i === 5) {
    continue;
  }
  console.log(i);
}

Try these exercises:

  1. Write a program that prints the first 10 Fibonacci numbers
  2. Create a function that uses a switch statement to convert day numbers to day names
  3. Use a for loop to calculate the factorial of a number
  4. Write code that uses break to find the first number greater than 100 that's divisible by both 7 and 11
  5. Create a type guard function that handles string, number, and boolean types differently

Key Takeaways

  • Use if-else for conditional logic
  • Switch statements are great for multiple discrete values
  • For loops iterate a specific number of times
  • For-of loops iterate over array values
  • While loops continue until a condition is false
  • Break exits a loop, continue skips to the next iteration
  • TypeScript's type system works with control flow for type narrowing

Pro Tip: Choose the right control structure for the job. For-of is great for arrays, while is better when you don't know how many iterations you need, and if-else handles complex conditions!

Control Flow | LearningTypeScript.org