All articles
How toDec 27, 2024 · 5 min read

Enums vs Object typing in typescript

Why should you move away from one of the bigger typescript functionalities? What would be the better alternative to enums? Read more in this blog post.

Antonio ŠumakFounder, AS Agency
Enums vs Object typing in typescript

1. What Are TypeScript Enums?

Enums in TypeScript let you define a set of named constants. While this might sound convenient, enums often include hidden complexities that can affect performance and debugging.

TypeScript
enum Environment {
  PRODUCTION = "PRODUCTION",
  DEVELOP = "DEVELOP",
  STAGE = "STAGE"
}

At first glance, this simple code snippet may appear harmless. However, enums can generate extra JavaScript code during the transpilation process, which can result in complex debugging issues and differences across various build environments.

TypeScript
export var Environment;
(function (Environment) {
    Environment["PRODUCTION"] = "PRODUCTION";
    Environment["DEVELOP"] = "DEVELOP";
    Environment["STAGE"] = "STAGE";
})(Environment || (Environment = {}));

This is what a typescript enum is compiled into. Why like this? To answer this question we have to go deeper that this example. What would happen if we would have this as an enum?

TypeScript
enum Environment {
  PRODUCTION,
  DEVELOP,
  STAGE
}

What do you think would happen when this gets compiled?

TypeScript
"use strict";
var Environment;
(function (Environment) {
    Environment[Environment["PRODUCTION"] = 0] = "PRODUCTION";
    Environment[Environment["DEVELOP"] = 1] = "DEVELOP";
    Environment[Environment["STAGE"] = 2] = "STAGE";
})(Environment || (Environment = {}));

Not what you've expected, right? This output might confuse you even more, but when you convert a Environment enum into an object you get this output

TypeScript
{
  "0": "PRODUCTION",
  "1": "DEVELOP",
  "2": "STAGE",
  "PRODUCTION": 0,
  "DEVELOP": 1,
  "STAGE": 2
} 

That is why there are number assignations, those numbers represent an index inside the enum.

How do you use enum as a type?

TypeScript
const getEnvironmentData = (env: Environment)=>{}

// Works ✅
getEnvironmentData(0)
getEnvironmentData(Environment.PRODUCTION)

// Doesn't work ❌
getEnvironmentData("PRODUCTION")

There is a way to remove the additional code overhead by using

TypeScript
const enum Environment {
  PRODUCTION = "PRODUCTION",
  DEVELOP = "DEVELOP",
  STAGE = "STAGE"
}

But this introduces additional edge case issues because this removes the whole object in the runtime.

2. Introducing Typed Objects

Typed objects utilize the as const feature in TypeScript, ensuring that the values remain literal types. This approach offers clarity and keeps your JavaScript output predictable.

TypeScript
const Environment = {
  PRODUCTION: "PRODUCTION",
  DEVELOPMENT: "DEVELOPMENT",
  STAGE: "STAGE"
} as const;

By using this as const annotation, each value in the object is treated as a literal type, maintaining type safety without the overhead that comes with enums. When compiled this is the output, no additional code.

While this removes additional complexity from the end compiled code, raw object can't be used as a type directly, we need to do some type manipulation. To use it as type in a way enum is used additional code is needed.

TypeScript
const Environment = {
  PRODUCTION: "PRODUCTION",
  DEVELOPMENT: "DEVELOPMENT",
  STAGE: "STAGE"
} as const;

type TEnviroment =  typeof Environment[keyof typeof Environment]

const getEnvironmentData = (env:  TEnviroment)=>{}

This is how to get the type out of the object, now how do we use it?

TypeScript
const getEnvironmentData = (env:  TEnviroment)=>{}

getEnvironmentData('PRODUCTION')
getEnvironmentData(Environment.PRODUCTION)

As you can see, you can type it like an enum, but then again you can provide it a string version of the value as in this case "PRODUCTION" is also a valid type. This means you don't need an additional import just for you to get the enum value.

Conclusion

This doesn't means that you can't or shouldn't use enums anymore. This blog post is about showing you that there are other, better solutions.

By using typed objects instead of enums, you gain:

  • Cleaner transpilation
  • Easier debugging
  • Better type safety
  • Streamlined code maintenance

At AS Agency, we believe these benefits contribute to building scalable, reliable, and future-proof applications. Typed objects are just one example of how we stay on the cutting edge of TypeScript best practices to deliver top-quality web development services for our clients.

Written by Antonio Šumak

Founder of AS Agency. I design and build fast websites for small businesses — and write down what I learn along the way.

Share

Booking Oct / Nov 2026 · 2 spots left

Ready to show the worldyour business?

Let’s talk about your idea on a free, friendly 30-minute call. You’ll leave with a clear plan and a fair quote.

Zagreb--:--New York--:--