Why Use Enum Utilities?
Traditional TypeScript enums have limitations:TypeScript Enums
- Generate runtime code
- Can’t be used in const contexts
- Limited type inference
- Non-standard JavaScript
defineEnum
- Zero runtime overhead
- Full const support
- Powerful type inference
- Plain JavaScript objects
Basic Usage
defineEnum
Create a type-safe enum with optional union extraction.- Basic Enum
- With Value Union
- With Key Union
Type Signature
Options
inferredUnionVariant
Controls which union type to infer.writeableLevel
Controls whether readonly modifiers are removed.- shallow (default)
- deep
defineEnumDeep
Convenience function for deep writeable enums.Type Signature
Practical Examples
HTTP Status Codes
API Routes
User Roles & Permissions
Event Types
Configuration Keys
Form Field Names
Comparison with Alternatives
- defineEnum
- TypeScript Enum
- Plain Object
- Union Type
Advanced Patterns
Nested Enums
Combining with Type Guards
Best Practices
When to Use defineEnum
When to Use defineEnum
Use
defineEnum when:- You need a set of related constants
- You want automatic union type extraction
- You prefer plain JavaScript objects over TypeScript enums
- You need to use values in const contexts
- You want zero runtime overhead
Choosing Union Variant
Choosing Union Variant
- Use
'values'when the enum values are what matter (e.g., status strings, error codes) - Use
'keys'when the property names are what matter (rare) - Use
'none'(default) when you don’t need union extraction
Shallow vs Deep
Shallow vs Deep
- Use
defineEnum(shallow) for simple enums with primitive values - Use
defineEnumDeepfor nested configuration objects - Deep mode has compile-time overhead for complex types
Naming Conventions
Naming Conventions
- Use PascalCase for enum objects:
UserRole,HttpStatus - Use UPPER_SNAKE_CASE for enum keys:
PENDING,NOT_FOUND - Use descriptive names that indicate purpose
See Also
Type Utilities
Learn about ExtractUnion and other utilities
Guards & Assertions
Validate enum values at runtime