TypeScript: Casting enums with same values gets error
TypeScript Version: 3.9.2
Search Terms:
Expected behavior: It would be great to check if all enum values are exclusively overlap, and only throw error when it is not.
Actual behavior: Now it shows error even when they have exactly same values:
Conversion of type 'EnumA' to type 'EnumB' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first.(2352)
Related Issues:
Code
export enum EnumA {
Key = 'VALUE',
}
export enum EnumB {
Key = 'VALUE',
}
function assign(val: EnumA) {
const val2: EnumB = val as EnumB; // <--- getting error here
return val2;
}
Output
export var EnumA;
(function (EnumA) {
EnumA["Key"] = "VALUE";
})(EnumA || (EnumA = {}));
export var EnumB;
(function (EnumB) {
EnumB["Key"] = "VALUE";
})(EnumB || (EnumB = {}));
function assign(val) {
const val2 = val;
return val2;
}
Compiler Options
{
"compilerOptions": {
"noImplicitAny": true,
"strictNullChecks": true,
"strictFunctionTypes": true,
"strictPropertyInitialization": true,
"strictBindCallApply": true,
"noImplicitThis": true,
"noImplicitReturns": true,
"useDefineForClassFields": false,
"alwaysStrict": true,
"allowUnreachableCode": false,
"allowUnusedLabels": false,
"downlevelIteration": false,
"noEmitHelpers": false,
"noLib": false,
"noStrictGenericChecks": false,
"noUnusedLocals": false,
"noUnusedParameters": false,
"esModuleInterop": true,
"preserveConstEnums": false,
"removeComments": false,
"skipLibCheck": false,
"checkJs": false,
"allowJs": false,
"declaration": true,
"experimentalDecorators": false,
"emitDecoratorMetadata": false,
"target": "ES2017",
"module": "ESNext"
}
}
Playground Link: Provided
About this issue
- Original URL
- State: closed
- Created 4 years ago
- Reactions: 6
- Comments: 15 (4 by maintainers)
Hey, any updates on this?
This could happen often, if you are migrating to graphql, and then generate all types including enums separately in graphql schema.
Does TS’s structural typing philosophy not extend to enums?
this seems to work
Would it be natural for the enum equivalent to work too?
@zlk89 this is exactly what I’m experiencing right now. This is our setup
.graphqlfiles generatingschema-types.tsfileA user makes a request to our GraphQL service, and we pass it along to our REST service.
Here is a shortened version of the generated
schema-types.ts(GraphQL input)And here are the OpenAPI generated types (BE)
Now trying to run
gives
Trying
gives
And of course I could just do
but that’s pretty #cringe haha
A bit late to the party but maybe someone can help me figure this one out.
I love the fact that enums are treated like nominal types – to be honest I’d like to see more options for nominal types in TS but that’s for a whole different discussion.
Basically I’m dealing with the same situation as OP so let us assume, just for the sake of this thought experiment, there is no other way.
Is there a type-safe way for me to cast one enum to the other? I.e. using some combination of conditional and mapped types? I tried creating a conditional type that would return
neverif keys of the source didn’t extend keys of the target (throughkeyof typeof Enum) so that the unsafe cast throughunknownwould still fail if the enums didn’t overlap, like so:but then I realised I can not assign anything to
never, but I can assignneverto anything so that idea went down the drain.Anyone got any other suggestions? 😅