All about Enum in Typescript

urstrulyvishwak

Kurapati Mahesh

Posted on November 15, 2022

All about Enum in Typescript

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,

  1. Numeric Enums
  2. String Enums
  3. Heterogeneous Enums

Numeric Enums.

enum Numeric {
    First,
    Second,
    Third,
    Fourth
}
console.log(Numeric.Second); // 1
Enter fullscreen mode Exit fullscreen mode
  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
Enter fullscreen mode Exit fullscreen mode
  1. 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",
}
Enter fullscreen mode Exit fullscreen mode

Heterogeneous enums

Mix of numeric and string enums.

enum HeterogeneousEnum {
    No = 0,
    Yes = 'YES'
}
Enter fullscreen mode Exit fullscreen mode
  1. 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
Enter fullscreen mode Exit fullscreen mode

ii. Declare types using the name of the enum.

(function myFunc(word, number: Numeric) {
    console.log(word + ' ' + direction);
})('word', Numeric.Second);
// word 1
Enter fullscreen mode Exit fullscreen mode
  1. Enum without initializers need to be first.
function getConstantValue() {
    return 1;
}

enum Numeric {
    first,
    second = getConstantValue(),
}
// first & second shouldn't be upside down.
Enter fullscreen mode Exit fullscreen mode
  1. Enums without initializers should come after initialized enums with numeric constants or other enum constants.like below:
enum Numeric {
    first = 2,
    second = A,
    third
}
Enter fullscreen mode Exit fullscreen mode

But not like below.

enum Numeric {
     first = 2,
     second = getConstantValue(), 
     third
 }
Enter fullscreen mode Exit fullscreen mode
  1. 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.
}
Enter fullscreen mode Exit fullscreen mode
  1. In All other cases enum member considered computed.

  2. 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
 }
Enter fullscreen mode Exit fullscreen mode
  1. 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
}
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
}
Enter fullscreen mode Exit fullscreen mode

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,
}
Enter fullscreen mode Exit fullscreen mode

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;
Enter fullscreen mode Exit fullscreen mode

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,
  };
Enter fullscreen mode Exit fullscreen mode

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) {
    }
  }
Enter fullscreen mode Exit fullscreen mode

Shows compilation error as: This condition will always return 'true' since the types 'Numeric.first' and 'Numeric.second' have no overlap.

πŸ’– πŸ’ͺ πŸ™… 🚩
urstrulyvishwak
Kurapati Mahesh

Posted on November 15, 2022

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related