Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.syntblaze.com/llms.txt

Use this file to discover all available pages before exploring further.

A union type is a composite type formed by combining two or more constituent types using the pipe operator (|). It declares that a value conforms to at least one of the specified types at compile time. Because TypeScript employs structural typing, a value may satisfy multiple constituent types simultaneously. Union types are strictly a compile-time construct and are erased during JavaScript emission, having no effect on runtime evaluation.
type PrimitiveUnion = string | number | boolean;

Property Access and Intersection

When a value is typed as a union, TypeScript restricts direct property access to the intersection of the constituents’ properties. You can only invoke methods or access properties that are guaranteed to exist across all types within the union.
interface Bird {
    fly(): void;
    layEggs(): void;
}

interface Fish {
    swim(): void;
    layEggs(): void;
}

declare const pet: Bird | Fish;

pet.layEggs(); // Valid: Shared across all constituents
// pet.fly();  // Error: Property 'fly' does not exist on type 'Bird | Fish'

Type Narrowing

To access members specific to a single constituent type, the union must be narrowed. TypeScript utilizes control flow analysis in conjunction with type guards (such as typeof, instanceof, the in operator, or custom type predicates) to deduce the specific type within a given lexical scope.
function processValue(val: string | number) {
    if (typeof val === "string") {
        // Control flow analysis narrows 'val' to string
        return val.toUpperCase(); 
    }
    // TypeScript infers 'val' is number in this branch
    return val.toFixed(2);
}

Discriminated Unions and Exhaustiveness Checking

A discriminated union (often called a tagged union) is a structural pattern where every constituent type in the union shares a common literal property, known as the discriminant. TypeScript leverages this discriminant to perform deterministic type narrowing, typically within switch statements or if/else chains. A primary mechanical benefit of discriminated unions is exhaustiveness checking. By assigning the unhandled cases to the never type in a default block, the compiler will enforce that all possible constituent types are evaluated. If a new type is later added to the union without updating the control flow, TypeScript will raise a compile-time error.
interface Circle {
    kind: "circle"; // Discriminant property
    radius: number;
}

interface Square {
    kind: "square"; // Discriminant property
    sideLength: number;
}

type Shape = Circle | Square;

function calculateArea(shape: Shape) {
    switch (shape.kind) {
        case "circle":
            // TypeScript narrows 'shape' to Circle
            return Math.PI * shape.radius ** 2;
        case "square":
            // TypeScript narrows 'shape' to Square
            return shape.sideLength ** 2;
        default:
            // Exhaustiveness checking: ensures all 'kind' literals are handled.
            // If a 'Triangle' is added to 'Shape', this line causes a compiler error.
            const _exhaustiveCheck: never = shape;
            return _exhaustiveCheck;
    }
}
Master TypeScript with Deep Grasping Methodology!Learn More