2

enter image description here

enum A {
   a = 1,
   b = 2
}

namespace N1 {
   export enum A {
       a = 1,
       b = 2
   }
}
// it will pass type check
console.log(A.a === N1.A.a)

when I remove const keyword, the expression will pass type check.

But if const was added, tsc says

This condition will always return 'false' since the types 'A' and 'N1.A' have no overlap.

I want to know how enums in TS compare enum value under the hood.

lynnic
  • 85
  • 1
  • 5

1 Answers1

1

According to the link

Const enums can only use constant enum expressions and unlike regular enums they are completely removed during compilation. Const enum members are inlined at use sites. This is possible since const enums cannot have computed members.

To illustrate consider below code -

enum A {
   a = 1,
   b = 2
}

namespace N1 {
   export const enum A {
       a = 1,
       b = 2
   }
}

console.log(N1.A.a);
console.log(A.a);

which will be transpiled to -

"use strict";
var A;
(function (A) {
    A[A["a"] = 1] = "a";
    A[A["b"] = 2] = "b";
})(A || (A = {}));
console.log(1);
console.log(A.a);

As you can see -

  1. There is no reference of const enum A in the transpiled code.
  2. The console output of printing N1.A.a converted to literal type 1.

So at compile time the literal type 1 and A.a cannot be compared and you have to typecast the const enum to number like below -

console.log(N1.A.a as number === A.a) 

You can further check the literal type comparison in below thread -

Operator '==' cannot be applied to types x and y in Typescript 2

MBB
  • 1,635
  • 3
  • 9
  • 19
  • if you add const keyword before first enum definition(the one without namespace), tsc will still show the same error. why literal type 1 can not be equal to literal type 1? – lynnic Aug 30 '20 at 14:38
  • I hope you went through the SO thread that I posted in my answer! For literal type comparisons typecast is required. – MBB Aug 30 '20 at 15:46