SyntaxStudy
Sign Up
TypeScript Arrays, Tuples, and Union Types
TypeScript Beginner 1 min read

Arrays, Tuples, and Union Types

Arrays in TypeScript can be typed in two equivalent ways: using the T[] shorthand or the generic Array form. Both declare an array whose elements must all be of type T. When you need an array with a fixed number of elements of specific types at specific positions, you use a tuple type. Union types allow a value to be one of several types, written with the pipe character, for example string | number. They are extremely common in TypeScript and appear in function parameters, return types, and state representations. When you have a union type you typically need to narrow it before accessing type-specific members. Intersection types, written with &, combine multiple types into one that must satisfy all of them simultaneously. They are useful for mixins and for composing object shapes. Unlike unions, which represent alternatives, intersections represent a value that is both types at once. Understanding the difference between unions and intersections is key to building flexible type-safe APIs.
Example
// Array types — two equivalent notations
const nums: number[] = [1, 2, 3];
const strs: Array<string> = ["a", "b", "c"];

// Read-only array
const constants: readonly number[] = [10, 20, 30];
// constants.push(40); // Error

// Tuple — fixed positions with specific types
type RGB = [red: number, green: number, blue: number];
const red: RGB = [255, 0, 0];
const [r, g, b] = red;

// Rest element in tuple
type StringsWithNumber = [string, ...string[], number];
const valid: StringsWithNumber = ["a", "b", "c", 42];

// Union types
type ID = string | number;
function printId(id: ID): void {
    if (typeof id === "string") {
        console.log(id.toUpperCase());
    } else {
        console.log(id.toFixed(0));
    }
}

// Discriminated union
type Shape =
    | { kind: "circle"; radius: number }
    | { kind: "rect"; width: number; height: number };

function area(s: Shape): number {
    switch (s.kind) {
        case "circle": return Math.PI * s.radius ** 2;
        case "rect":   return s.width * s.height;
    }
}

// Intersection types
type Named = { name: string };
type Aged  = { age: number };
type Person = Named & Aged;

const alice: Person = { name: "Alice", age: 30 };