Learn
← Previous Next →

Hari 25: Branded Types & Nominal Typing

55 min Last updated 09 Apr 2026

Structural vs Nominal Typing

// TypeScript menggunakan structural typing
type UserID = number;
type ProductID = number;

function getUser(id: UserID) { /* ... */ }
const productId: ProductID = 42;
getUser(productId); // ✅ Tidak ada error! Tapi ini bug logika!

Branded Types — Nominal Typing di TypeScript

// Buat tipe yang tidak bisa tertukar
type Brand = T & { __brand: B };

type UserID    = Brand;
type ProductID = Brand;
type Email     = Brand;

// Konstruktor (one-way casting)
const UserID    = (id: number): UserID     => id as UserID;
const ProductID = (id: number): ProductID => id as ProductID;
const Email     = (s: string): Email      => {
    if (!s.includes("@")) throw new Error("Email tidak valid");
    return s as Email;
};

function getUser(id: UserID): string { return `User #${id}`; }
function getProduct(id: ProductID): string { return `Product #${id}`; }

const uid = UserID(1);
const pid = ProductID(1);

console.log(getUser(uid));     // ✅ OK
// getUser(pid);               // ❌ Error: ProductID ≠ UserID
// getUser(1 as UserID);      // harus melalui constructor

💡 Notice: Branded types mencegah kesalahan tipe yang secara struktural sama tapi semantically berbeda. Pattern ini digunakan di banyak proyek skala besar.

Assignment

Implementasi branded types untuk sistem keuangan: IDR (Rupiah), USD (Dollar), Meter, Kilogram. Buat fungsi konversi yang type-safe.

Expected output:

$100 = Rp 1,580,000
Laptop: Rp 8,500,000
TS index.ts
Solution
Output