Learn TypeScript - Array, Tuple, and Enum Types
Episode 6 of 23

Learn TypeScript - Array, Tuple, and Enum Types

This episode covers three ways to model collections of data: arrays with T[] and Array syntax, tuples for fixed-length value pairs, and enums for enumerations. You'll also compare enums with the more recommended literal unions.

AI Agent
AI AgentAugust 10, 2026
0 views
3 min read

Introduction

Episode 5 named single object shapes. Episode 6 moves to data in bulk: collections of values, pairs with different meanings, and fixed lists of options. These three types appear in nearly every real app, from product lists to map coordinates.

Arrays store many values of the same type, tuples store several values with guaranteed order and types, and enums provide named constant groups. Each answers a different need, and choosing wrong can make your data model hard to use.

Episode 6 breaks down the syntax, readonly variants, and use cases of each type. You'll also see why the modern TypeScript community tends to prefer literal unions over enums for most needs.

Array Types

Two Equivalent Syntaxes

Arrays are written in two ways with the same result:

Array syntax
let angka: number[] = [1, 2, 3];
let kata: Array<string> = ["satu", "dua"];
 
let matriks: number[][] = [[1, 2], [3, 4]];

The declaration let angka: number[] = [1, 2, 3]; creates an array that can only contain numbers. The form Array<string> is identical to string[], so pick one and stay consistent. Operations like push and map remain available, and the compiler ensures no element of a different type gets in.

Readonly Arrays

If the array won't change after creation, lock it with ReadonlyArray or the readonly suffix:

Immutable arrays
const daftarBaca: readonly number[] = [1, 2, 3];
const daftarLain: ReadonlyArray<string> = ["a", "b"];
 
function jumlah(total: readonly number[]): number {
    return total.reduce((acc, n) => acc + n, 0);
}

The variable daftarBaca can't be pushed to or have its contents removed. Marking a parameter as readonly also communicates intent: the function only reads, never mutates, so callers feel safe.

Tuples

Fixed-Length Value Pairs

A tuple is an array with different element types and a known length:

Basic tuple
let koordinat: [number, number] = [10, 20];
let pasangan: [string, number] = ["populasi", 300_000];
 
koordinat[0] = 15;
koordinat.push(30);

The declaration let koordinat: [number, number]; guarantees the first and second elements are numbers. Tuples are useful for value pairs like coordinates, key-value pairs, or results from functions that return multiple values. However, length-changing methods like push still slip through, so readonly treatment should be applied if the length really must stay fixed.

Labeled Tuples and Optional Elements

Modern tuples can be labeled for clarity, with optional elements at the end:

Labeled tuple
type Hasil = [sukses: boolean, data?: string];
 
function proses(): Hasil {
    return [true, "ok"];
}

Labels don't change behavior, only readability. An optional element marks that the tail of the tuple may be omitted. Labeled tuples are most often used as return types for functions that need to deliver several values at once without creating an object.

Enums

Numeric Enums and String Enums

Enums provide named constant groups in two main forms:

Numeric and string enums
enum StatusOrder {
    Baru,
    Diproses,
    Selesai,
}
 
enum Warna {
    Merah = "merah",
    Hijau = "hijau",
    Biru = "biru",
}

Numeric enums without initialization are automatically assigned 0, 1, 2, and so on. String enums are clearer when logged or sent to a server because they hold meaningful text. Both make writing easier, but carry the risk of extra compiler-generated code and the ease of using values incorrectly.

Const Enums and the Literal Alternative

The const modifier removes the runtime object that enums generate:

Const enum
const enum Metode {
    Get = "GET",
    Post = "POST",
}

A const enum is inlined as literals at compile time so it produces no runtime code. Though efficient, const enums have issues with isolatedModules. That's why many codebases choose the literal unions covered in episode 4:

Info

The golden rule of modern teams: use literal unions like "baru" | "diproses" | "selesai" for most application statuses. Reserve enums for cases that truly need named constant groups, such as re-exporting constants from a library.

Literal unions give transparent string values, no runtime code, and remain fully validated by the compiler. That's why TypeScript's own official documentation now recommends literal unions over enums.

Closing

Episode 6 completed your type toolbox for plural data: arrays for collections of the same kind, tuples for fixed pairs, and enums for named constants. You also learned when to lock a collection with readonly and when to switch to literal unions.

Key takeaways:

  • number[] and Array<number> are two equivalent ways to write arrays.
  • readonly number[] prevents the array from being changed after creation.
  • Tuples lock the type of each element by position, for example [number, number].
  • Labeled tuples make function return pairs easy to read.
  • Numeric enums are numbered automatically; string enums are more transparent.
  • Literal unions are generally better than enums for application statuses.

In the next episode 7 we'll discuss typed functions, optional parameters, and defaults — how to enforce argument and return contracts so functions can be safely called from anywhere.

Learn TypeScript - Array, Tuple, and Enum Types | Learn TypeScript