• Home
  • Skills
  • Projects
  • Blog
  • Contact
Resume
Naser Rasouli

Author

Naser Rasouli

Front-End developer - sharing lessons learned, notes, and write-ups from real projects.

GitHubLinkedIn

Last posts

Static RBAC: Roles & Permissions in React
2025-12-20•1 min read

Static RBAC: Roles & Permissions in React

A lightweight RBAC pattern to guard routes and UI in React with static roles and permissions.

Conventional Commits: Write Better Git Messages
2025-12-12•1 min read

Conventional Commits: Write Better Git Messages

Master Git commit messages with Conventional Commits to keep history readable and automation-friendly.

Mastering Git Flow
2025-12-08•1 min read

Mastering Git Flow

Mastering Git Flow: A Developer’s Guide to Branching Strategies

Mastering Record in TypeScript

Mastering Record in TypeScript

2025-12-13
typescriptrecordenumstype-safety

Introduction

Need a reliable way to attach labels, icons, or colors to an enum without scattering switch statements? Record gives you a single, type-safe map so UI metadata stays centralized, predictable, and easy to extend. This guide shows how it works with both union types and real-world enums.


What is Record in TypeScript?

Record<K, T> creates an object type whose keys must be of type K and whose values must be of type T. It is perfect for mapping a fixed set of keys to structured metadata.

// Union type of possible roles
type UserRole = "admin" | "user" | "guest";

// Keys must be each role; values must be strings
const roles: Record<UserRole, string> = {
  admin: "Administrator",
  user: "Regular User",
  guest: "Guest User",
};

// Safe lookup
console.log(roles.admin); // "Administrator"

// Error: TypeScript prevents unknown keys
// roles.superAdmin = "Super Admin";

This pattern guarantees full coverage of all keys and prevents accidental extras.


Using Record with enums (UI metadata)

Enums show up everywhere in production apps. Suppose you need labels and colors for payment statuses:

enum PaymentStatus {
  Unpaid = 0,
  Paid = 1,
  Failed = 2,
}

Instead of repeating switch statements, create one source of truth:

const paymentStatusMeta: Record<
  PaymentStatus,
  { label: string; color: string }
> = {
  [PaymentStatus.Unpaid]: { label: "Unpaid", color: "orange" },
  [PaymentStatus.Paid]: { label: "Paid", color: "green" },
  [PaymentStatus.Failed]: { label: "Failed", color: "red" },
};

Now you can render metadata directly:

const status = PaymentStatus.Paid;
console.log(paymentStatusMeta[status].label); // "Paid"
console.log(paymentStatusMeta[status].color); // "green"

Helper function for cleaner usage

Wrap lookups to keep call sites expressive and future-proof:

function getPaymentStatusMeta(status: PaymentStatus) {
  return paymentStatusMeta[status];
}

// Usage
const info = getPaymentStatusMeta(PaymentStatus.Failed);
console.log(info.label); // "Failed"
console.log(info.color); // "red"

If you later add localization or formatting, you update the function without touching the rest of your codebase.


Why prefer Record over switch/case?

  • Full coverage enforced: TypeScript requires every enum or union key to exist in the map.
  • Strong typing: Values must match the declared shape, preventing accidental mismatches.
  • Centralized metadata: Labels, colors, and icons live in one place.
  • Cleaner reads: meta[status].label is easier to scan than repeated switch statements.
  • Safer extensions: Adding a new enum value forces you to supply its metadata at compile time.

Summary

  • Record<K, T> builds a type-safe map from known keys to structured values.
  • Use it to store UI metadata for enums or union types instead of scattered switches.
  • Wrap lookups in a helper to add localization or formatting later without refactors.
  • The compiler enforces full coverage and correct value shapes, reducing runtime bugs.

Conclusion

Record keeps enum metadata centralized, readable, and type-safe. Use it as the single source of truth for anything your UI needs to display for a given status or role, and let TypeScript enforce completeness for you. Happy coding!