Mastering Record in TypeScript: The Clean Way to Map Enums to Labels and Colors
Naser Rasouli

Naser Rasouli @naserrasouli

About: I'm a frontend developer with a strong focus on building clean, maintainable code and designing flexible project architectures. Passionate about creating responsive user interfaces, I excel both in co

Joined:
Mar 13, 2025

Mastering Record in TypeScript: The Clean Way to Map Enums to Labels and Colors

Publish Date: Aug 22
3 2

“Have you ever needed to display user-friendly labels, icons, or colors for numeric enums in TypeScript? Many devs either use switch statements or ad-hoc objects — but there’s a cleaner, type-safe way: Record.”

What is Record in TypeScript?

Short definition: Record is an object type with keys of type K and values of type T.
Think of it as a type-safe way to define “maps” from a known set of keys to specific values.
Here’s a very simple example using a union type:

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

// Record<UserRole, string> means:
//   - keys must be "admin" | "user" | "guest"
//   - 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 won’t let you add an unknown key
// roles.superAdmin = "Super Admin";

Enter fullscreen mode Exit fullscreen mode

This ensures you don’t forget a key, and you can’t accidentally add extra ones.

Using Record with enums (real-world example)

Union types are nice, but in real-world projects we often work with enums. Let’s say you have an enum that represents payment statuses in your application:

enum PaymentStatus {
  Unpaid = 0,
  Paid = 1,
  Failed = 2,
}
Enter fullscreen mode Exit fullscreen mode

If you want to display labels and colors in your UI for each status, the naive way would be a bunch of switch statements. Instead, Record gives us a cleaner, safer approach:

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" },
};
Enter fullscreen mode Exit fullscreen mode

Now, wherever you need metadata for a given status:

const status = PaymentStatus.Paid;
console.log(PaymentStatusMeta[status].label); // "Paid"
console.log(PaymentStatusMeta[status].color); // "green"
Enter fullscreen mode Exit fullscreen mode

Helper function for cleaner usage
Instead of directly accessing PaymentStatusMeta every time, you can wrap it in a function:

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

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

This makes the code more expressive and also helps if later you need to add logic (like localization or formatting) inside the function without touching the rest of your codebase.

Why use Record? (Advantages)

Using Record in TypeScript to map enums (or unions) to metadata brings several benefits:

Full coverage enforced by TypeScript

  • TypeScript ensures that every key in your enum or union is included in the Record.
  • Forgetting a case results in a compile-time error, preventing runtime bugs.

Strong type safety

  • Values inside the Record must match the type you specify.
  • No more accidentally assigning a string where an object is expected.

Extensible with metadata

  • You can easily add more fields, like icon, tooltip, localeLabel, etc.

Cleaner than switch/case statements

  • No repeated switch statements scattered across your codebase.
  • Lookup is simple and readable: PaymentStatusMeta[status].label

Predictable and maintainable

  • Future developers immediately know where to find mappings. Adding a new enum value only requires updating one place.

If you found this guide useful:
✅ Save it for future reference.
🔁 Share it with your team or developer friends.
💬 Comment below with your favorite TypeScript patterns or how you handle enum metadata in your projects.

Happy coding! 🚀

Comments 2 total

Add comment