A TypeScript switch statement selects one execution path by comparing an expression with a series of case values. It is useful when the same variable or computed value must be checked against several known alternatives, such as command names, status codes, string literal types, or enum members.

TypeScript follows JavaScript’s switch behavior. Case matching uses strict equality, so values of different types do not match even when they look similar. TypeScript adds compile-time type checking and narrowing around that JavaScript behavior.

TypeScript switch statement syntax

The expression after switch is evaluated once. TypeScript then checks the case clauses in source order. Execution starts at the first matching case, or at default when no case matches.

Syntax

Following is the syntax of TypeScript switch statement:

</>
Copy
    switch (expression){
        case constant1 : {
            // this is first case block
            break
        }
        case constant2 : {
            // this is second case block
            // and there can be any number of cases
            break
        }
        default : {
            // when no case is matched, this block executes
            break
        }
    }
  • A switch statement can contain any practical number of case clauses.
  • A case label may contain an expression. Its result is compared with the switch value by using strict equality (===).
  • A break statement exits the switch. Without break, return, or throw, execution falls through to the following case body.
  • The optional default clause handles values that do not match a case. It is commonly placed last, although JavaScript syntax does not require that position.
  • Duplicate case values should be avoided because only the first matching label can be reached through normal case matching.

TypeScript switch example with numbers

In this example, the switch expression is the sum of two variables. The sum is 4, so execution starts in case 4. Its break statement then prevents execution from continuing into the next case.

example.ts

</>
Copy
var a:number = 1
var b:number = 3

switch (a+b){
    case 1 : {
        console.log("a+b is 1.")
        break
    }
    case 3 : {
        console.log("a+b is 3.")
        break
    }
    case 4 : {
        console.log("a+b is 4.")
        break
    }
    case 5 : {
        console.log("a+b is 5.")
        break
    }
    default : {
        console.log("a+b is 5.")
        break
    }
}

When the above typescript file is compiled using tsc example.ts , following JavaScript file is generated.

example.js

</>
Copy
var a = 1;
var b = 3;
switch (a + b) {
    case 1: {
        console.log("a+b is 1.");
        break;
    }
    case 3: {
        console.log("a+b is 3.");
        break;
    }
    case 4: {
        console.log("a+b is 4.");
        break;
    }
    case 5: {
        console.log("a+b is 5.");
        break;
    }
    default: {
        console.log("a+b is 5.");
        break;
    }
}

Output

a+b is 4.

How TypeScript switch case matching works

Case matching uses strict equality. A numeric value such as 2 therefore does not match the string "2". TypeScript usually reports incompatible comparisons before the program runs when it can determine that the switch expression and case value have unrelated types.

</>
Copy
const accessLevel: string = "editor";

switch (accessLevel) {
    case "admin":
        console.log("Full access");
        break;
    case "editor":
        console.log("Content access");
        break;
    default:
        console.log("Read-only access");
}

A case label is not limited to a literal constant. It can be an expression, although simple literals, enum members, and named constants are normally easier to read. Case expressions are evaluated only as needed while the switch searches for a match.

TypeScript switch case with multiple matching values

Place multiple case labels before one statement block when several values require the same result. The empty cases intentionally fall through until execution reaches the shared code.

</>
Copy
function getDayType(day: string): string {
    switch (day.toLowerCase()) {
        case "saturday":
        case "sunday":
            return "weekend";
        case "monday":
        case "tuesday":
        case "wednesday":
        case "thursday":
        case "friday":
            return "weekday";
        default:
            return "invalid day";
    }
}

This pattern represents multiple alternative values, not arbitrary boolean conditions. When each branch depends on a different range or compound condition, an if...else if chain is generally clearer.

Using break, return, and fall-through in a switch

Use break when control should continue with the statement after the switch. Inside a function, return both supplies a result and exits the function, so an additional break would be unreachable and unnecessary. A thrown error also ends the current switch path.

If a matching case finishes without one of these control-flow statements, execution continues into later case bodies without testing their labels again. This is called fall-through. Grouped labels use it intentionally, but accidental fall-through is a common source of defects.

</>
Copy
function getPriorityLabel(priority: number): string {
    switch (priority) {
        case 1:
            return "High";
        case 2:
            return "Normal";
        case 3:
            return "Low";
        default:
            return "Unknown";
    }
}

TypeScript switch assignment and switch expressions

TypeScript does not provide a built-in switch expression that directly evaluates to a value. A regular switch is a statement. To assign a result, declare a variable before the switch and assign it in every relevant branch, or place the switch in a function and return from each case.

</>
Copy
type Plan = "basic" | "team" | "enterprise";

function getSeatLimit(plan: Plan): number {
    switch (plan) {
        case "basic":
            return 1;
        case "team":
            return 10;
        case "enterprise":
            return 100;
    }
}

Returning from every case is concise and avoids a mutable result variable. In this example, the union type also limits callers to the three supported plan names.

TypeScript switch with enum values

Enum members can be used as case labels. Referencing the member names is clearer and safer than repeating their underlying numeric or string values.

</>
Copy
enum OrderStatus {
    Pending,
    Processing,
    Shipped,
    Cancelled
}

function describeOrder(status: OrderStatus): string {
    switch (status) {
        case OrderStatus.Pending:
            return "Waiting for processing";
        case OrderStatus.Processing:
            return "Being prepared";
        case OrderStatus.Shipped:
            return "Sent to the customer";
        case OrderStatus.Cancelled:
            return "Order cancelled";
        default:
            return "Unknown order status";
    }
}

Exhaustive TypeScript switch for discriminated unions

A discriminated union gives every variant a shared property with a distinct literal value. Switching on that property narrows the variable inside each case. An assignment to never in the default branch makes the compiler report an error when a new union member is added but not handled.

</>
Copy
type ApiResult =
    | { kind: "success"; data: string }
    | { kind: "failure"; message: string }
    | { kind: "loading" };

function displayResult(result: ApiResult): string {
    switch (result.kind) {
        case "success":
            return result.data;
        case "failure":
            return `Error: ${result.message}`;
        case "loading":
            return "Loading...";
        default: {
            const unhandled: never = result;
            return unhandled;
        }
    }
}

If another kind is later added to ApiResult, the never assignment fails during type checking until a corresponding case is implemented. This provides compile-time exhaustiveness checking rather than relying on a general fallback result.

When to use switch instead of if…else in TypeScript

  • Use switch when one expression is compared with several exact values.
  • Use grouped cases when multiple exact values share one action.
  • Use if...else for ranges, unrelated predicates, and compound conditions such as age >= 18 && hasId.
  • Use an object or Map when known keys simply map to values or functions and no branch-specific control flow is needed.
  • Use an exhaustive switch when each member of a union must receive distinct handling.

TypeScript switch implementation checklist

  • Confirm that every case value is compatible with the switch expression’s type.
  • Check whether each case deliberately exits with break, return, or throw.
  • Group multiple case labels only when they are intended to share the same body.
  • Provide a meaningful default path for unexpected runtime input, or use a never check for an exhaustive union.
  • Test at least one matching case, the default or invalid-input path, and any intentional fall-through behavior.

TypeScript switch case FAQs

Can a TypeScript switch case contain multiple conditions?

Several exact values can share a branch by stacking case labels. For boolean ranges or compound conditions, use if...else because it states the conditions more directly.

Does TypeScript switch use strict equality?

Yes. Case matching follows JavaScript and uses strict equality semantics. For example, the number 1 does not match the string "1".

Can a TypeScript switch return a value?

A switch is a statement rather than an expression, so it does not itself produce a value. A function can return a value from each case, or each case can assign to a variable declared outside the switch.

What happens when break is omitted from a TypeScript case?

Execution continues into the following case body until it encounters a break, return, throw, or the end of the switch. The later case labels are not tested again during this fall-through.

Does TypeScript support pattern matching in switch statements?

TypeScript does not add a separate pattern-matching switch syntax. Discriminated unions provide similar type-safe branching: switch on the shared discriminant property, let TypeScript narrow each variant, and use never to check exhaustiveness.

In this TypeScript Tutorial, we covered switch syntax, strict case matching, grouped cases, fall-through, return-based branches, enum values, and exhaustive handling of discriminated unions.