enumHttpStatus{Ok=200,Created=201,BadRequest=400,Unauthorized=401,NotFound=404,ServerError=500,}functionisSuccessful(status:HttpStatus): boolean {return status >=200&& status <300;}console.log(isSuccessful(HttpStatus.Ok));// trueconsole.log(HttpStatus.NotFound);// 404
Output
// true
// 404
Note Numeric enums auto-increment from the last explicit value. If no values are assigned, they start at 0. Beware: TypeScript allows assigning ANY number to a numeric enum variable, not just declared members - this is a known type safety gap.
numeric enumenum with numbersauto increment enumHTTP status enum
String Enums
Syntax
enumName{Member="value",}
Example
enumLogLevel{Debug="DEBUG",Info="INFO",Warn="WARN",Error="ERROR",Fatal="FATAL",}functionlog(level:LogLevel, message: string){console.log(`[${level}] ${message}`);}log(LogLevel.Error,"Database connection lost");// log("ERROR", "..."); // Error: '"ERROR"' is not assignable to 'LogLevel'
Output
// [ERROR] Database connection lost
Note String enums do NOT auto-increment - every member needs an explicit string value. They are more type-safe than numeric enums because you cannot accidentally pass an arbitrary string. The downside: you cannot pass the raw string value, only the enum member.
string enumenum with stringsnamed constantsenum values
const Enums
Syntax
constenumName{Member= value,}
Example
constenumDirection{Up="UP",Down="DOWN",Left="LEFT",Right="RIGHT",}const playerDirection =Direction.Up;// Compiles to: const playerDirection = "UP";// No Direction object exists at runtime
Output
// const enums are completely erased - values are inlined at compile time
Note const enums produce zero runtime JavaScript - member accesses are replaced with literal values. However, they have compatibility issues: they cannot be used with --isolatedModules (Babel, esbuild, SWC), and they do not work across declaration files in some setups. Many teams ban them in favor of plain unions.
enumPermission{Read="READ",Write="WRITE",Admin="ADMIN",}// Each member is its own typefunctiongrantAdmin(userId: string, level:Permission.Admin){console.log(`Granting admin to ${userId}`);}grantAdmin("usr_1",Permission.Admin);// OK// grantAdmin("usr_1", Permission.Read); // Error: not assignable to Permission.Admin
Output
// Individual enum members can be used as specific types
Note Each enum member is a subtype of the enum. You can use individual members in type positions to restrict parameters to a specific enum value. This is more useful with string enums since numeric enum members have the wider number type.
enum member typespecific enum valueenum subtypenarrow enum
Reverse Mapping (Numeric Enums)
Syntax
EnumName[numericValue]// returns the member name as string
Example
enumPriority{Low=0,Medium=1,High=2,Critical=3,}const level =Priority.High;console.log(level);// 2console.log(Priority[level]);// "High"// Practical: converting API response to labelfunctiongetPriorityLabel(code: number): string {returnPriority[code]??"Unknown";}
Output
// 2
// "High"
Note Reverse mapping ONLY works with numeric enums - string enums do not generate reverse mappings. The compiled JavaScript includes both name→value and value→name entries in the enum object. const enums do not support reverse mapping since they have no runtime object.
reverse mappingenum name from valuenumeric enum lookupenum to string
Union Types as Enum Alternatives
Syntax
typeName="value1"|"value2"|"value3";
Example
// Instead of enum:typeTheme="light"|"dark"|"system";// Object const pattern for when you need both runtime values and typesconstTHEMES={Light:"light",Dark:"dark",System:"system",}asconst;typeTheme2=(typeofTHEMES)[keyoftypeofTHEMES];// "light" | "dark" | "system"functionapplyTheme(theme:Theme2){document.body.dataset.theme= theme;}
Output
// Union types achieve the same result without enum's quirks
Note Many TypeScript teams prefer string literal unions over enums for simplicity, full tree-shaking, and compatibility with --isolatedModules. The 'as const' object pattern gives you both runtime values (for iteration/lookup) and a derived type - the best of both worlds.