Arrays, Tuples & Enums

Difficulty: Beginner

Question

Explain arrays, tuples, and enums in TypeScript. When would you use each?

Answer

Arrays, tuples, and enums are three fundamental collection/value types in TypeScript:

Arrays: Ordered collections of a single type (or union). Use number[] or Array<number> syntax. Best for lists of homogeneous items.

Tuples: Fixed-length arrays where each position has a specific type. Use [string, number] syntax. Best for returning multiple values from functions or representing structured pairs.

Enums: Named sets of constants. Can be numeric (default) or string-based. Best for a fixed set of known values. Consider using string literal unions as a lighter alternative.

Code examples

Arrays and Readonly Arrays

// Typed arrays
const numbers: number[] = [1, 2, 3];
const names: Array<string> = ['Alice', 'Bob'];

// Union type arrays
const mixed: (string | number)[] = [1, 'two', 3];

// Readonly arrays - cannot be mutated
const frozen: readonly number[] = [1, 2, 3];
// frozen.push(4);  // Error: Property 'push' does not exist
// frozen[0] = 10;  // Error: Index signature is readonly

// ReadonlyArray utility type
function processItems(items: ReadonlyArray<string>): void {
  // items.push('new'); // Error: cannot mutate
  console.log(items.length); // OK: reading is fine
}

// Array methods return types
const doubled = numbers.map(n => n * 2);    // number[]
const found = numbers.find(n => n > 1);      // number | undefined
const filtered = names.filter(n => n.length > 3); // string[]

Use readonly arrays for function parameters to prevent accidental mutation. TypeScript correctly infers return types of array methods.

Tuples

// Basic tuple - fixed length, typed positions
let point: [number, number] = [10, 20];
let entry: [string, number] = ['age', 30];

// Named tuple elements (documentation only)
type Coordinate = [x: number, y: number, z: number];
const pos: Coordinate = [1, 2, 3];

// Optional tuple elements
type ColorRGB = [number, number, number, alpha?: number];
const red: ColorRGB = [255, 0, 0];
const transparentRed: ColorRGB = [255, 0, 0, 0.5];

// Tuples as return types
function useState<T>(initial: T): [T, (val: T) => void] {
  let state = initial;
  const setState = (val: T) => { state = val; };
  return [state, setState];
}
const [count, setCount] = useState(0); // [number, (val: number) => void]

// Rest elements in tuples
type StringAndNumbers = [string, ...number[]];
const data: StringAndNumbers = ['sum', 1, 2, 3, 4];

Tuples are perfect for functions returning multiple values (like React's useState). Named elements improve readability without runtime cost.

Enums vs String Literals

// Numeric enum (default)
enum Direction {
  Up,      // 0
  Down,    // 1
  Left,    // 2
  Right,   // 3
}
const dir: Direction = Direction.Up;

// String enum - more readable in debugging
enum Status {
  Active = 'ACTIVE',
  Inactive = 'INACTIVE',
  Pending = 'PENDING',
}

// const enum - inlined at compile time (no runtime object)
const enum Color {
  Red = 'RED',
  Green = 'GREEN',
  Blue = 'BLUE',
}
const c = Color.Red; // Compiles to: const c = 'RED';

// Alternative: string literal union (often preferred)
type StatusLiteral = 'active' | 'inactive' | 'pending';
const userStatus: StatusLiteral = 'active';

// String literals have better tree-shaking and are simpler
// Enums create a runtime object; literal unions do not

String enums are readable but add runtime overhead. String literal unions are often preferred in modern TypeScript for their simplicity and better tree-shaking.

Key points

Concepts covered

Arrays, Tuples, Enums, const Enums, Readonly Arrays