</> AICS
TypeScript Enum Naming

TypeScript Enum Naming Standards

Consistent naming conventions for TypeScript enums, ensuring predictable code generation and maintainable type-safe constants across your project.

TypeScript Enum Naming Standards

Enums are a powerful TypeScript feature, but inconsistent naming patterns confuse both developers and AI coding tools. Clear enum naming standards ensure predictable generated code and maintainable type-safe constants.


Why Enum Naming Matters

Poorly named enums cause:

  • AI tools generating incorrect enum member references
  • Confusion between enum types and their member values
  • Inconsistent casing that breaks linting rules
  • Difficulty distinguishing enums from regular objects
  • Import ambiguity when multiple enums share similar names

Core Naming Rules

1. PascalCase for Enum Names

Enum type names always use PascalCase to distinguish them from variables and functions.

Correct:

enum UserRole { ... }
enum HttpStatus { ... }
enum PaymentMethod { ... }
enum SortDirection { ... }

Incorrect:

enum userRole { ... }      // camelCase for a type name
enum http_status { ... }   // snake_case for a type name
enum HTTPSTATUS { ... }     // UPPER_CASE for a type name

2. PascalCase for Enum Members

Use PascalCase for enum members, not UPPER_SNAKE_CASE. This is the TypeScript recommended convention.

Correct:

enum UserRole {
  Admin,
  Editor,
  Viewer,
  Guest
}

Incorrect:

enum UserRole {
  ADMIN,      // UPPER_CASE - looks like a constant, not an enum member
  EDITOR,
  VIEWER,
  GUEST
}

3. Singular Nouns for Enum Names

Enum names should be singular since each value represents a single member of the set.

Correct:

enum Status { Active, Inactive, Pending }
enum Category { Tech, Finance, Health }
enum Theme { Light, Dark, System }

Incorrect:

enum Statuses { Active, Inactive, Pending }    // Plural
enum Categories { Tech, Finance, Health }       // Plural

String vs Numeric Enums

Numeric Enums

Use when the actual numeric value has no meaning - the member names are the API.

enum Priority {
  Low,
  Medium,
  High,
  Critical
}
// Priority.Low = 0, Priority.Medium = 1, etc.

String Enums

Use when the value must be serialized (API responses, localStorage) or when debugging clarity matters.

enum HttpStatus {
  Ok = "OK",
  NotFound = "NOT_FOUND",
  InternalError = "INTERNAL_ERROR",
  BadRequest = "BAD_REQUEST"
}

String enum values use UPPER_SNAKE_CASE to signal serialized wire format.


Const Enums

Use const enum for zero-runtime-overhead constants consumed within the same project.

const enum Direction {
  Up,
  Down,
  Left,
  Right
}

Avoid const enum in library code - they break when consumed as external modules. Use regular enums or union types instead.

// ❌ Library export - breaks consumers
export const enum Theme { Light, Dark }

// ✅ Library export - works everywhere
export enum Theme { Light, Dark }

When to Use Enum vs Union Type

ScenarioUse EnumUse Union Type
Values have auto-incrementing numeric IDs
Values need runtime iteration
Values come from external API as strings
Values are small and stable
Library API - avoid runtime overhead
Need reverse mapping (value -> name)
// ✅ Enum - stable set with numeric IDs
enum StatusCode {
  Success,
  Pending,
  Failed
}

// ✅ Union type - small, stable, serializable
type SortOrder = "asc" | "desc"

// ❌ Avoid enum when a union would work
enum Color { Red = "red", Green = "green", Blue = "blue" }
// Better as:
type Color = "red" | "green" | "blue"

Enum File Organization

Place related enums in dedicated type files or co-located with their usage module.

types/
  user.types.ts        -> UserRole, AccountStatus, SubscriptionTier
  order.types.ts       -> OrderStatus, PaymentMethod, ShippingMethod
  api.types.ts         -> HttpStatus, ApiErrorCode, ContentType

Co-located

features/
  billing/
    billing.types.ts   -> InvoiceStatus, BillingCycle, PaymentGateway
    BillingForm.tsx

Incorrect

types/
  enums.ts             // Single file with every enum - hard for AI to find

Flag Enums (bit flags)

Use descriptive member names that compose naturally.

enum Permission {
  None = 0,
  Read = 1 << 0,
  Write = 1 << 1,
  Delete = 1 << 2,
  Admin = Read | Write | Delete
}

State Machine Enums

Use past-tense verb for states, present-tense for actions.

enum OrderState {
  Created,
  Confirmed,
  Shipped,
  Delivered,
  Cancelled,
  Returned
}

Common Mistakes

Mistake 1: Heterogeneous Values

Mixing string and numeric values in the same enum.

// ❌ Confusing - mixed types
enum Status { Active = 1, Inactive = "inactive" }

// ✅ Consistent - all string
enum Status { Active = "ACTIVE", Inactive = "INACTIVE" }

Mistake 2: Computed Values

Avoid computed values - they break AI tool autocomplete and reverse mapping.

// ❌ AI can't predict the value
enum Size { Small = 10, Medium = 20, Large = Small + Medium }

// ✅ Static values
enum Size { Small = 10, Medium = 20, Large = 30 }

Mistake 3: Unused Enums

Each enum should be imported and used in at least two places. Single-use enums should be union types.


AI Coding Prompt Example

When generating TypeScript enums in this project:
- Use PascalCase for enum type names and enum members
- Use singular nouns for enum names
- Prefer string enums for serialized values with UPPER_SNAKE_CASE values
- Prefer union types for small (3-5 values), stable sets
- Group related enums in domain-specific type files
- Avoid const enum in shared library code
- Avoid heterogeneous values and computed members

Best Practices Summary

  • PascalCase for enum names and members
  • Singular nouns for enum names
  • String enums with UPPER_SNAKE_CASE for serialized values
  • Union types for small stable sets
  • Group enums by domain in dedicated type files
  • Avoid const enum in public library APIs
  • Document enum semantics with JSDoc comments
Advertisement