2

I'm having enums with identical values but different names:

enum EnumA{
  HELLO,
  WORLD
}
enum EnumB{
  HELLO,
  WORLD
}

As you they are bot generated by an external source an have the same values, but are used in an component where it can be EnumA or EnumB.

let x: EnumA | EnumB = EnumA.HELLO;
// or
let x: EnumA | EnumB = EnumB.HELLO;

If I wan to check for HELLO I need to

if(x === EnumA.HELLO || x === EnumB.HELLO)

Is there an easier way to do this check or tell typescript that these two enums are identical?

Something like:

const x: EnumA | EnumB = EnumB.HELLO;

if(x === EnumA.HELLO) {
    console.log('they are the same')
}

If I try this I get the typescript warning:

This condition will always return 'false' since the types 'EnumB.HELLO' and 'EnumA.HELLO' have no overlap.

But the console.log is called! Demo: https://www.typescriptlang.org/play/#code/KYOwrgtgBAouEEEDeBYAUFTUASMAyeA8gDTpZQDqhASngCLoC+6oks8AQqhlrgSWSxVaDNMzToAxgHsQAZwAuUAB4AudpARQAPhogcoAXj0cAdHyIBudOgCWAMwAUyo4eNxN5-EQCUUbuQy8tIANsCmIdIA5o4A5AoAFsAAnlAAhgBOwFCJ2XJpEMCxPkxAA

Uwe Keim
  • 39,551
  • 56
  • 175
  • 291
Stefan
  • 14,826
  • 17
  • 80
  • 143
  • Possible duplicate of [How to compare Enums in TypeScript](https://stackoverflow.com/questions/39785320/how-to-compare-enums-in-typescript) – Roberto Zvjerković Jul 03 '19 at 09:39
  • Not a duplicate because the question is about one enum, this one is for two enums with identical values, wich should be compared – Stefan Jul 03 '19 at 09:59

2 Answers2

2

Union-type variables are narrowed by control-flow analysis upon assignment. That means the line

const x: EnumA | EnumB = EnumA.HELLO;

ends up narrowing the type of x all the way to type EnumA.HELLO, and it is considered an error to compare two unrelated types like EnumA.HELLO and EnumB.HELLO.

If you want to prevent this from happening so that x can be compared to both an EnumA and an EnumB you can use a type assertion like this:

const x = EnumB.HELLO as EnumA | EnumB;

Then the comparison will work:

if (x === EnumA.HELLO) { } // okay

Link to code


But if both EnumA and EnumB are generated by an external source and you know they will be identical, then it seems like a headache to allow them to appear as different types in the first place. I don't know enough about your code to suggest how to address this... only import EnumA and ignore EnumB? Merge EnumA and EnumB into a single object and only reference the combined EnumAB? Not sure.


Anyway, hope that helps. Good luck!

jcalz
  • 264,269
  • 27
  • 359
  • 360
1

ok so this

const x: EnumA | EnumB = EnumB.HELLO;

if(x === EnumA.HELLO) {
    console.log('they are the same')
}

throw error since u are comparing const wich is EnumB.HELLO and ts can see this.

if u get the value from function like this

const a = (): EnumA | EnumB => {
  return EnumA.HELLO;
};
const x: EnumA | EnumB = a();

if (x === EnumB.HELLO) {
  console.log('they are the same');
}

that's correct and runtime will pass the condition since this is the same number

the other solution is to compare it like number.

const x: number = EnumA.HELLO;

if (x === EnumB.HELLO) {
  console.log('they are the same');
}

and again runtime will pass the condition since this is the same number...

Juraj Kocan
  • 2,648
  • 1
  • 15
  • 23
  • I like the solution but it still feels kinda hacky... I was hoping for a online solution :) – Stefan Jul 03 '19 at 14:27
  • what do you mean by online solution? – Juraj Kocan Jul 03 '19 at 14:28
  • spellchecker... one line solution, so to solve my problem in just one simple line, which is somewhere referenced in the official documantion :) () PS: if nobody gives a better solution I will accapt yours in a few days) – Stefan Jul 03 '19 at 14:41
  • well the one line solution is const x: number = EnumA.HELLO;... if you compare different enums ts will ofc always throw error. what you want is to compare its numeric value so you can compare different enums value what can be same – Juraj Kocan Jul 04 '19 at 07:56
  • what you did is [this](https://www.typescriptlang.org/play/#code/MYewdgzgLgBAhgLhgRhgHxgJhgXiwbgFgAoKATwAcBTGAWzIBVKa9zqQAzeGAeh5igALAJYQYomGBCxUGbHDBlaIAE40ARlWBwQEGp3FhhUYXAA2wgF5wT4GCWFcAFHFw48yAJQwA3iRgwoJAgZlQAdGYgAOZOAEQMImJBACbGwnYA7sJmZvBmGXBkYmpQAK4qYDAA5BzmelUwEMJgwDRCbcxiVZgNCsnVyA2CcABuNFIwIGMqZnAUYbGeJAC+QA) same error since you try to compare exact value what ts can see... – Juraj Kocan Jul 04 '19 at 08:28