-
Notifications
You must be signed in to change notification settings - Fork 12.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Enums does not support literal typing with computed values #27976
Comments
This is still a design limitation. For mostly historical reasons we have two fundamentally different kinds of enums in the language, numeric and literal. Numeric enums are just like the
We chose to do it this way such that we didn't have to introduce an explicit modifier to choose between the two kinds. This still holds. The only way I can see us allowing computed constant expressions for literal enum members is to introduce a modifier, e.g. |
Is there any chance of revisiting this? This would allow for composition of enums. My use case is this, as part of an integration with the HubSpot CRM where booleans are passed as "yes"/"no": // either
export enum HubspotBool {
True = 'yes',
False = 'no',
}
// or
export const HUBSPOT_TRUE = 'yes';
export const HUBSPOT_FALSE = 'no';
// doesn't matter which
export enum CustomerIdentityCheckStatus {
Completed = HubspotBool.True, // fails
NotCompleted = HUBSPOT_FALSE, // fails
Failed = 'failed',
} I know it's not super necessary but it's the sort of thing I would expect to "just work", where as currently it gives me an unexpected error which leads me here. |
In the typescript documents, it says each enum member has a value associated with it which can be either constant or computed. enum FileAccess { But the computed doesn't work as the documents described, and throws an error in Vue3 SFC. |
It's ok that you can define the numeric enum "FileAccess" which has both computed and constant members. However, if you want to use the enum member as a type, the members of the numeric enum must be initialized by literal. const num = 1;
// it‘s ok
enum UserResponse {
// constant member
No = 0,
// computed member
Yes = num,
// constant member
NotSure = 1 + 1
}
// throws an error : Enum type has members with initializers that are not literals
type aType = UserResponse.Yes;
// throws an error : Enum type has members with initializers that are not literals
type bType = UserResponse.NotSure;
// it‘s ok
enum UserResponse_1 {
// constant member initialized by literal
No = 0,
// constant member initialized by literal
Yes = 1,
// constant member initialized by literal
NotSure = 2,
}
// it's ok
type aType_1 = UserResponse_1.Yes;
type bType_1 = UserResponse_1.NotSure; In addition, this problum has been resolved in 5.0. |
TypeScript Version: 3.2.0-dev.201xxxxx
Search Terms:
Code
Expected behavior:
a
Should have type ofAnimalFlags.EatsFish
b
Should not throw. Should allow the assignment ofAnimalFlags.EndangeredFlyingClawedFishEating
as type.I would expect a computed Enum to behave as a regular enum, in this case,
c
has typeRegularEnum.HasPowers
Actual behavior:
a
is typed asAnimalFlags
.const b: AnimalFlags.EndangeredFlyingClawedFishEating
is throwingEnum type 'AnimalFlags' has members with initializers that are not literals.
b
should be allowed to be typed asAnimalFlags.EndangeredFlyingClawedFishEating
.Playground Link:
Link
Related Issues:
I think is the same that one reported last year #18393. It was closed as a Design Limitation, but since there has been some big changes in Typescript maybe this would be worth to be reviewed again.
The text was updated successfully, but these errors were encountered: