Enum vs union literal type trade-offs in Typescript - Performance Comparison
We want to see how using enums or union literal types affects the speed of our code.
How does the choice between these two affect how long operations take as data grows?
Analyze the time complexity of the following code snippet.
enum ColorEnum {
Red = "red",
Green = "green",
Blue = "blue"
}
type ColorUnion = "red" | "green" | "blue";
function isPrimaryColorEnum(color: ColorEnum): boolean {
return color === ColorEnum.Red || color === ColorEnum.Blue;
}
function isPrimaryColorUnion(color: ColorUnion): boolean {
return color === "red" || color === "blue";
}
This code checks if a color is primary using either an enum or a union literal type.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: Simple equality checks in conditional statements.
- How many times: Each check runs once per function call.
Since the checks are simple comparisons, the time does not grow with input size.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | 2 checks |
| 100 | 2 checks |
| 1000 | 2 checks |
Pattern observation: The number of operations per function call is constant (2 equality checks), independent of input size.
Time Complexity: O(1)
This means each check runs in constant time, no matter the input size.
[X] Wrong: "Using enums is slower because they add extra code overhead."
[OK] Correct: Both enums and union literals compile to simple values, so their runtime checks are equally fast.
Understanding how different type choices affect performance helps you write clear and efficient code, a skill valued in real projects and interviews.
"What if we added a loop to check many colors at once? How would the time complexity change?"
Practice
Solution
Step 1: Understand enums and union literal types
Enums create named objects that exist in the generated JavaScript code at runtime. Union literal types only exist during TypeScript's type checking and do not produce runtime code.Step 2: Compare runtime presence
Since union literal types are erased after compilation, they cannot be used as runtime objects, unlike enums.Final Answer:
Enums create runtime objects, while union literal types only exist at compile time. -> Option AQuick Check:
Runtime object presence = A [OK]
- Thinking union types generate runtime code
- Believing enums cannot restrict values
- Confusing dynamic assignment capabilities
Solution
Step 1: Identify union literal type syntax
Union literal types use the syntax: type Name = 'value1' | 'value2' | 'value3';Step 2: Check options for correct syntax
type Colors = 'red' | 'green' | 'blue'; correctly uses the union literal type syntax. Options B and D misuse enum syntax, and C defines a tuple type, not a union.Final Answer:
type Colors = 'red' | 'green' | 'blue'; -> Option BQuick Check:
Union literal type syntax = A [OK]
- Using enum syntax for union types
- Using array syntax instead of union
- Assigning enum with = and union syntax mixed
enum StatusEnum { Active = 'active', Inactive = 'inactive' }
type StatusUnion = 'active' | 'inactive';
const enumValue = StatusEnum.Active;
const unionValue: StatusUnion = 'active';
console.log(enumValue === 'active');
console.log(unionValue === 'active');Solution
Step 1: Understand enum and union values
StatusEnum.Active is assigned the string 'active'. The unionValue is also the string 'active'.Step 2: Evaluate the console.log comparisons
Both enumValue === 'active' and unionValue === 'active' compare string 'active' to 'active', so both are true.Final Answer:
true true -> Option DQuick Check:
String equality for enum and union = D [OK]
- Assuming enum values are numbers by default
- Thinking enumValue is an object, not a string
- Confusing enum and union value types
enum Direction {
Up = 'UP',
Down = 'DOWN'
}
type DirectionUnion = 'UP' | 'DOWN';
function move(dir: DirectionUnion) {
console.log(dir);
}
move(Direction.Up);
move('LEFT');Solution
Step 1: Check function parameter type
Function move expects a parameter of type DirectionUnion, which allows only 'UP' or 'DOWN'.Step 2: Analyze function calls
Calling move(Direction.Up) passes 'UP', which is valid. Calling move('LEFT') passes a string not in the union, causing a type error.Final Answer:
Calling move with 'LEFT' causes a type error. -> Option CQuick Check:
Invalid union argument = B [OK]
- Assuming enum values are incompatible with union types
- Thinking missing enum values cause errors
- Believing function parameter types are flexible
// Option 1
enum UserRoleEnum { Admin = 'admin', User = 'user', Guest = 'guest' }
// Option 2
type UserRoleUnion = 'admin' | 'user' | 'guest';Solution
Step 1: Understand runtime and type safety needs
To check values at runtime, you need an actual JavaScript object. Enums generate this object. Union types only exist at compile time and do not generate code.Step 2: Compare options for runtime checks and type safety
UserRoleEnum provides both runtime presence and type safety. UserRoleUnion provides only type safety but no runtime object for checks.Final Answer:
Use UserRoleEnum because it creates a runtime object for checks and type safety. -> Option AQuick Check:
Runtime object + type safety = C [OK]
- Thinking union types generate runtime code
- Believing enums cannot restrict string values
- Assuming union types can be used for runtime checks
Ready to prove it?
Pass the test and this pattern moves unknown
