tsc
permits basic interchangeable usage of two different enum declarations so long as both enum names and each enums members are the same. For example, the below assignments are valid, namespaces
are used here, but this is observed to extend to TS module declarations and separate files.
namespace X {
export enum Colour {
Blue,
Green,
}
}
namespace Y {
export enum Colour {
Green,
Blue
}
}
// assign a Colour enum from Y to a variable with a Colour enum type from X
let greenXY: X.Colour = Y.Colour.Green; // OK
// assign a Colour enum from X to a variable with a Colour enum type from Y
let blueYX: Y.Colour = X.Colour.Blue; // OK
// and equality
let greenX = X.Colour.Green;
let isGreen = greenX == Y.Colour.Green; // OK
Now consider the const
enums with the same structure:
namespace X {
export const enum ConstColour {
Green,
Blue
}
}
namespace Y {
export const enum ConstColour {
Green,
Blue
}
}
// assign a const Colour enum from Y to a variable with a const Colour enum type from X
let greenConstXY: X.ConstColour = Y.ConstColour.Green; // Type 'ConstColour.Green' is not assignable to type 'ConstColour'.(2322)
// assign a Colour enum from Y to a variable with a Colour enum type from X
let blueConstYX: Y.ConstColour = X.ConstColour.Blue; // Type 'ConstColour.Blue' is not assignable to type 'ConstColour'.(2322)
// and equality
let constGreenX = X.ConstColour.Green;
let isConstGreen = constGreenX == Y.ConstColour.Green; // This condition will always return 'false' since the types 'X.ConstColour' and 'Y.ConstColour' have no overlap.(2367)
We know that const
enums are inlined at use sites to the desired value and that tsc
views enums as a union type of its members which is how tsc
knows the types of which enums comprise.
And so if tsc
is able to reliably determine the correct basic usage of two regular enums at compile-time. Why would const
enums differ in this case?
Playground Link
A known bug, microsoft/TypeScript#29879, is unfortunately confusing you. Neither enum
nor const enum
are intended to be interchangeable in this way. I see you mentioned that TS supports this if they have the same names, but having the same name in different namespaces should not have any significance... and if you change your enum
declaration so that they have different names (say, Color
in X
and Colour
in Y
):
namespace X {
export enum Color {
Green,
Blue,
}
}
namespace Y {
export enum Colour {
Green,
Blue
}
}
you get the same errors as you get with your const enum
:
let greenXY: X.Color = Y.Colour.Green; // error!
let blueYX: Y.Colour = X.Color.Blue; // error!
let greenX = X.Color.Green;
let isGreen = greenX == Y.Colour.Green; // error!
The assignability of same-name-in-different-namespace enum
s is not intentional; it's a weird bug, and apparently not important enough to be fixed in the short term (it's been relegated to the backlog).
Not sure what to tell you to do about it. Personally I stay as far away from enum
s as I can since they are an older feature that doesn't adhere to TypeScript's design goals... there are no enum
s in ECMAScript. Any proposal to add a similar feature to TypeScript today where you implement new expression-level syntax without it first existing in at least a Stage 3 proposal for ECMAScript would be declined.
Instead of enum
I sometimes roll my own equivalent like:
namespace U {
export const Colour = {
Green: 0,
Blue: 1
} as const;
export type Colour = typeof Colour[keyof typeof Colour];
}
namespace V {
export const Colour = {
Green: 0,
Blue: 1
} as const;
export type Colour = typeof Colour[keyof typeof Colour];
}
which is more tedious but, in my opinion, behaves better because the type Colour
is just a union of numeric literals 0 | 1
which are always interchangeable:
let greenUV: U.Colour = V.Colour.Green;
let greenVU: V.Colour = U.Colour.Green;
let greenU = U.Colour.Green;
let isGreenU = greenU === V.Colour.Green;
But that's just my opinion.
Anyway, hope this helps make sense of the situation. Good luck!
Playground link to code
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With