Enums are used to define named constants in Typescript. It's the typescripts own feature which is not a type level extension of javascript. It is defined using enum
keyword.
Typescript has three types of enums:
Namely,
- Numeric Enums
- String Enums
- Heterogeneous Enums
Numeric Enums.
enum Numeric {
First,
Second,
Third,
Fourth
}
console.log(Numeric.Second); // 1
- A numeric enum's first member is not initialized then it starts from 0 and
Second
becomes 1.
enum Numeric {
First = 1,
Second,
Third,
Fourth
}
console.log(Numeric.Second); // 2
- Numeric enum is now initialized with 1 hence starts from 1 and
Second
becomes 2.
String Enums
An enum which is initialized with string literal is called String enum.
enum StringEnum {
A = "a",
B = "b",
C = "c",
D = "d",
}
Heterogeneous enums
Mix of numeric and string enums.
enum HeterogeneousEnum {
No = 0,
Yes = 'YES'
}
- Duplicate Identifier is not allowed in Enum.
Using an enum
i. Access any member as the property of enum itself.
console.log(Numeric.Second); // 1
ii. Declare types using the name of the enum.
(function myFunc(word, number: Numeric) {
console.log(word + ' ' + direction);
})('word', Numeric.Second);
// word 1
- Enum without initializers need to be first.
function getConstantValue() {
return 1;
}
enum Numeric {
first,
second = getConstantValue(),
}
// first & second shouldn't be upside down.
- Enums without initializers should come after initialized enums with numeric constants or other enum constants.like below:
enum Numeric {
first = 2,
second = A,
third
}
But not like below.
enum Numeric {
first = 2,
second = getConstantValue(),
third
}
- Each enum member has a value associated with it which can be either constant or computed.
enum constNComputeEnum {
first = 1,
second = first, // reference to previously defined constant enum member.
third = (1 + 2), // parenthesized constant enum expression,
fourth = +true, // Unary operator applied.
fifth = 1 & 2 // binary operator applied.
}
In All other cases enum member considered computed.
Computed values are not permitted in an enum with string valued members.
like below:
enum constNComputeEnum {
first = 1,
second = 'second',
third = constNComputeEnum.first, // not allowed
}
- It is a compile time error for constant enum expressions to be evaluated to NaN or Infinity.
Ideally, below is not accepted but somehow not throwing any error.
I checked with latest typescript and is not throwing any error.
enum NaNNInfinity {
first = 0 / 0, // Result in NaN
second = 1 / 0, // Result in Infinity
}
Reverse Mapping
Numeric enum members can get a reverse mapping from enum values to enum names.
enum reverseMappingEnum {
first
}
const firstItem = reverseMappingEnum.first;
console.log(reverseMappingEnum[firstItem]); // first
const enums.
To avoid generating extra js code we can declare any enum as const. These are completely removed after compilation and can't have computed members.
It is recommended to not use const enums at all.
const enum constEnum {
first
}
Compile above and check its corresponding js file and you find nothing.
Ambient Enums
Regular Enums: Member that doesn't have initializer will be considered const if its preceding enum member considered const.
Ambient Enums: Member that doesn't have initializer will be considered as computed.
enum AmbientEnum {
first = 1,
second,
third = 2,
}
Object vs Enums
Typescript Enum exactly equal to object with as const.
const enum Numeric {
first,
second,
third,
fourth,
}
const Numeric = {
first: 0,
second: 1,
third: 2,
fourth: 3,
} as const;
Literal Enum
A literal enum member is a constant enum member with no initialized value, or with values that are initialized to
- any string literal (e.g. "first", "second")
- any numeric literal (e.g. 1 to 100)
- a unary minus applied to any numeric literal (e.g. -2, -4)
Enum members also become types as well!
enum Numeric {
thirty,
forty,
}
interface Person {
age: Numeric.thirty;
id: number
}
let c: thirty = {
age: Numeric.forty,
id: 100,
};
Shows compilation error as: Type 'Numeric.forty' is not assignable to type 'Numeric.thirty'.
Enum types themselves effectively become a union of each enum member.
enum Numeric {
first,
second,
}
function myFunc(type: Numeric) {
if (type !== Numeric.first || type !== Numeric.second) {
}
}
Shows compilation error as: This condition will always return 'true' since the types 'Numeric.first' and 'Numeric.second' have no overlap.
Top comments (0)