Control Flow in TypeScript
Learn conditionals, loops, switch statements, and type narrowing for control flow in TypeScript with Docker-ready examples
Control flow determines the order in which your program’s statements execute. Instead of running top to bottom, you can branch based on conditions, repeat work with loops, and select between many cases. TypeScript inherits all of JavaScript’s control flow constructs—if/else, switch, for, while—and adds something JavaScript can’t: control flow analysis. The compiler tracks how conditions narrow a value’s type as execution flows through each branch.
As a multi-paradigm language, TypeScript lets you write imperative loops, functional iteration with array methods, or expression-based conditionals. This tutorial focuses on the core imperative constructs while highlighting where TypeScript’s static type system makes control flow safer than plain JavaScript.
The standout feature is type narrowing. When you check if (typeof x === "string"), TypeScript knows that inside that block, x is a string—and it will let you call string methods without complaint. This connection between runtime checks and compile-time types is what makes TypeScript control flow feel different from JavaScript.
Conditionals: if, else if, else
The if statement runs a block when a condition is truthy. Conditions are evaluated as booleans, and TypeScript flags comparisons that can never be true.
Create a file named conditionals.ts:
| |
Each else if is checked only when the previous conditions were false, so the first matching branch wins.
Ternary and Logical Operators
For simple either/or choices, the ternary operator condition ? a : b is an expression that returns a value. TypeScript also offers the nullish coalescing operator ?? and optional chaining ?., which are common control-flow tools when dealing with possibly-missing values.
Create a file named ternary.ts:
| |
Note the difference between ?? and ||: ?? only falls back on null or undefined, while || falls back on any falsy value (including 0 and "").
Switch Statements and Type Narrowing
The switch statement compares a value against multiple case labels. TypeScript narrows the type inside each case, which is especially powerful with union types. Always include a break (or return) to avoid fall-through.
Create a file named switch_flow.ts:
| |
Because Direction is a union of string literals, TypeScript verifies that each case is a valid member. If you misspell a case label, the compiler reports an error.
Loops: for, while, and for…of
TypeScript supports the classic C-style for loop, the while loop, and the for...of loop for iterating over arrays and other iterables. Loop control statements break and continue work as expected.
Create a file named loops.ts:
| |
Use for...of to iterate over values directly. For index-based access or arbitrary step sizes, the C-style for loop is clearer.
Running with Docker
You can run each example without installing Node.js by using the official node:22-alpine image. ts-node compiles and runs TypeScript in a single step.
| |
Expected Output
Running conditionals.ts:
Score 95 => Grade A
Score 82 => Grade B
Score 71 => Grade C
Score 64 => Grade F
Running ternary.ts:
online
offline
Welcome, Ada!
Welcome, guest!
Running switch_flow.ts:
north => dx=0, dy=1
east => dx=1, dy=0
south => dx=0, dy=-1
west => dx=-1, dy=0
Running loops.ts:
Sum 1..5 = 15
T-minus 3
T-minus 2
T-minus 1
T-minus 0
Evens: 2, 4, 6
Key Concepts
- Type narrowing — Conditions like
typeof x === "string"or checking against union literals refine a value’s type within a branch, giving you safe access to type-specific members. - Exhaustive switches — When switching over a string-literal union, TypeScript can verify you handled every case, catching missing branches at compile time.
??vs||— Nullish coalescing falls back only onnull/undefined; logical OR falls back on any falsy value. Choose based on whether0and""are valid.for...offor values — Iterate values directly withfor...of; reach for the C-styleforloop only when you need an index or custom step.- Loop control —
breakexits a loop entirely, whilecontinueskips to the next iteration. - Ternary is an expression — Unlike
if, the?:operator returns a value, making it ideal for inline assignments and return statements. - Truthiness still applies — TypeScript uses JavaScript’s truthiness rules, but the compiler warns when a condition is always true or always false.
Comments
Loading comments...
Leave a Comment