enum Direction {
Up, // 0
Down, // 1
Left, // 2
Right // 3
}
console.log(Direction.Up); // 0
Topics
26
Classes: Access Modifiers, Abstract Classes & Implements
Conditional Types
Declaration Files
Decorators
Discriminated Unions & Exhaustiveness Checking
Enums
Function Types, Overloads & Optional/Default Parameters
Generics
Index Signatures & Record Types
Mapped Types
Migrating JavaScript to TypeScript
Modules
Namespaces & Declaration Merging
Never, Unknown & Void Types
Nullability: strictNullChecks, Optional Chaining & Nullish Coalescing
Primitive Types, Arrays & Tuples
Readonly, const Assertions & Immutability
Structural Typing & Duck Typing
Template Literal Types
tsconfig & Compiler Options
Type Assertions & Type Casting
Type Inference & Contextual Typing
Type Narrowing & Guards
Types & Interfaces
Union & Intersection Types
Utility Types
Enums
10 questions found
A numeric enum assigns sequential integer values starting at 0 to each member by default, unless you explicitly assign a starting value — subsequent members then auto-increment from there.
Real-world example
Representing a fixed set of directions, statuses, or days of the week with meaningful names instead of magic numbers.
Primitive Types
Arrays & Tuples
A string enum explicitly assigns a distinct string literal to each member (no auto-incrementing), which makes debugging easier since logged/serialized values are meaningful text rather than opaque numbers, and prevents accidental numeric type coercion between unrelated enums.
enum Status {
Active = 'ACTIVE',
Inactive = 'INACTIVE',
Pending = 'PENDING'
}
console.log(Status.Active); // 'ACTIVE'
Real-world example
Representing an order or subscription status where the readable string value is also what gets sent to or received from an API.
Union & Intersection Types
Numeric enums generate a two-way lookup object at runtime — you can go from name to value AND from value back to name (Direction[0] === 'Up'). String enums only generate a one-way object, since having numeric values map back to keys would be ambiguous/meaningless for string values.
enum Direction { Up, Down }
console.log(Direction.Up); // 0
console.log(Direction[0]); // 'Up' -- reverse mapping, numeric enums only
Real-world example
Converting a stored numeric status code back into its readable name for logging or display purposes.
Primitive Types
Arrays & Tuples
What is a 'const enum' and how does it differ from a regular enum in the compiled output?
IntermediateA const enum is fully inlined at every usage site during compilation and produces NO actual runtime object at all — usages of Direction.Up are replaced directly with the literal value 0 in the emitted JavaScript, resulting in smaller, faster output, at the cost of losing the ability to iterate over enum values at runtime.
const enum Direction { Up, Down }
let d = Direction.Up;
// compiles to roughly: let d = 0; -- no Direction object exists at runtime
Real-world example
Using const enums for performance-sensitive, high-frequency code where the small object-creation overhead of a regular enum matters.
tsconfig & Compiler Options
How do computed and constant enum members work when mixing string and numeric-style initialization?
IntermediateEnum members can be constant (a literal, or computed from prior members) or 'computed' (derived from a non-constant expression) — TypeScript requires that any UNINITIALIZED member following a computed one must have an explicit value, since it can no longer safely auto-increment from an unknown runtime expression.
function getValue() { return 10; }
enum Mixed {
A = 1,
B = getValue(), // computed
// C would need an explicit value here -- can't auto-increment after a computed member
C = 20
}
Real-world example
Rarely needed directly, but useful to understand when debugging why TypeScript demands an explicit value after certain enum members.
Primitive Types
Arrays & Tuples
Why do many style guides recommend using a union of string literal types instead of an enum in modern TypeScript?
AdvancedUnion literal types (`type Status = 'active' | 'inactive'`) require zero runtime code (fully erased, unlike regular enums which generate a real object), work naturally with plain string values from JSON/APIs without any conversion, and integrate more smoothly with generic type inference — enums add real runtime overhead and some quirky edge-case behaviors that literal unions avoid entirely.
// Enum: generates a runtime object, less flexible with raw string values
enum Status { Active = 'ACTIVE', Inactive = 'INACTIVE' }
// Literal union: zero runtime cost, works directly with API string values
type Status = 'ACTIVE' | 'INACTIVE';
Real-world example
Choosing a literal union over an enum specifically because API responses already send raw string values that need no conversion.
Union & Intersection Types
How does TypeScript's structural type checking treat two DIFFERENT numeric enums that happen to have the same underlying values?
AdvancedUnlike most structural comparisons, TypeScript treats numeric enum members as NOMINALLY distinct from each other by name even when their underlying values match — you cannot assign a member of one numeric enum to a variable typed as a different numeric enum, even if both equal 0, though plain numbers CAN still be assigned to a numeric enum variable.
enum A { X = 0 }
enum B { Y = 0 }
let a: A = A.X;
// let bad: A = B.Y; // Error: Type 'B' is not assignable to type 'A'
let ok: A = 0; // OK -- plain numbers are still assignable
Real-world example
Understanding a confusing compiler error when trying to pass one enum's member where a structurally-identical-looking different enum is expected.
Structural Typing & Duck Typing
Use Object.values(EnumName) to get an array of the enum's values (safe for string enums, since they don't generate reverse-mapping numeric keys), optionally typed explicitly as an array of the enum type for full type safety when iterating.
enum Status { Active = 'ACTIVE', Inactive = 'INACTIVE' }
const allStatuses = Object.values(Status) as Status[];
allStatuses.forEach(s => console.log(s)); // 'ACTIVE', 'INACTIVE'
Real-world example
Populating a dropdown's options dynamically from every possible enum value, without hardcoding the list separately.
Primitive Types
Arrays & Tuples
declare enum describes an enum that ALREADY EXISTS at runtime (typically defined in plain JavaScript or another compiled module) without generating any new runtime code itself — used in .d.ts files to describe a third-party library's runtime enum-like object so TypeScript can type-check code that references it.
// library.d.ts
declare enum Color {
Red,
Green,
Blue
}
// no JS object is generated here -- it must already exist at runtime, provided by the library
Real-world example
Writing a declaration file for a JavaScript library that exports an enum-like object, so TypeScript users of that library get type checking.
Declaration Files
How would you model a set of flags/permissions using a numeric enum with bitwise values, and how do you check if a flag is set?
AdvancedAssign each enum member a distinct power-of-two value so they can be safely combined with the bitwise OR operator into a single number representing multiple flags at once; check whether a specific flag is present using the bitwise AND operator against that flag's value.
enum Permission {
Read = 1 << 0, // 1
Write = 1 << 1, // 2
Delete = 1 << 2 // 4
}
const userPerms = Permission.Read | Permission.Write; // 3
const canWrite = (userPerms & Permission.Write) !== 0; // true
Real-world example
Representing a user's combined set of permissions (read/write/delete) compactly as a single stored integer.
Never
Unknown & Void Types