Skip to Content
Course content

95: String Enums vs Numeric Enums

Click on the "Edit" button in the top corner of the screen to edit your slide content.

By now, you've seen that enums are great for keeping a set of related constants in one place. But when you actually start typing them out, you'll notice TypeScript gives you a choice: you can let the compiler handle the values (numeric) or you can define them yourself (string). Let's clear up which one you should actually be using.

If I don't assign values to my enum, what's actually happening?

If you leave the values blank, TypeScript creates a numeric enum. It starts at 0 and increments by one for every member. It feels convenient because it's less typing, but it's often a trap for beginners.

enum OrderStatus {
  Pending,   // 0
  Shipped,   // 1
  Delivered, // 2
  Cancelled  // 3
}

const currentStatus = OrderStatus.Pending; 
console.log(currentStatus); // Output: 0

Here's the problem: if you later decide to insert a new status, like Processing, between Pending and Shipped, all the numbers after it shift. If you've already saved these numbers in a database, you've just corrupted your data. I've seen this happen in production more times than I'd like to admit.

Why should I bother writing out the strings?

String enums require you to initialize every member. It's more verbose, sure, but the payoff is huge when it comes to debugging and API integration.

enum OrderStatus {
  Pending = "PENDING",
  Shipped = "SHIPPED",
  Delivered = "DELIVERED",
  Cancelled = "CANCELLED"
}

const currentStatus = OrderStatus.Pending;
console.log(currentStatus); // Output: "PENDING"

Imagine you're staring at a log file at 2:00 AM. Seeing OrderStatus: 2 tells you absolutely nothing unless you have the source code open in another window. Seeing OrderStatus: "DELIVERED" tells you exactly what's happening. Plus, since the value is explicitly defined, you can reorder the enum members or add new ones without breaking any existing logic or database records.

I've heard something about "reverse mapping"—does that work for both?

This is one of those TypeScript quirks that confuses people. Numeric enums support reverse mapping, meaning you can go from the value back to the name.

enum OrderStatus {
  Pending, // 0
  Shipped  // 1
}

console.log(OrderStatus.Pending); // 0
console.log(OrderStatus[0]);       // "Pending"

String enums do not support this. If you try OrderStatus["PENDING"] on a string enum, it won't give you the key name back. In my experience, you almost never actually need reverse mapping in a real-world app, so this isn't usually a reason to choose numeric enums over string ones.

Which one should I actually use in a real project?

If you're undecided, go with string enums. 95% of the time, they are the right choice because they are self-documenting and safer for data persistence. Use numeric enums only if the actual integer value is meaningful to your logic (like mapping to specific HTTP status codes or bitwise flags) or if you have a very strict memory constraint where storing a small integer is critical.




📋 Practical Task

Refactoring the Legacy Order Tracker

You've inherited a project where the previous developer used a numeric enum for shipment tracking. The app is currently crashing because a new status was added in the middle of the enum, shifting the IDs and causing the frontend to misinterpret "Processing" orders as "Shipped".

Your task:

  • Locate the ShipmentStatus numeric enum.
  • Convert it into a string enum so that the values are explicit and won't shift when new members are added.
  • Ensure the values match these strings: "Warehouse", "InTransit", "OutForDelivery", and "Arrived".
  • Update the logStatus function to handle the new string values.
// FIX THIS CODE
enum ShipmentStatus {
  Warehouse,
  InTransit,
  OutForDelivery,
  Arrived
}

function logStatus(status: ShipmentStatus) {
  console.log(`The package is currently: ${status}`);
}

logStatus(ShipmentStatus.InTransit);
Rating
0 0

There are no comments for now.

to be the first to leave a comment.