-
Notifications
You must be signed in to change notification settings - Fork 12.6k
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
Enable constants as computed values for string enums #40793
Comments
This would be a perfectly valid feature to implement since computed number values are already allowed. Is there any reason why computed string values shouldn't be allowed for enums? Perhaps I'm not aware of something tied to the bigger picture? @RyanCavanaugh can anybody from the TS team comment on my assumptions above? Thanks a lot. |
I'm also curious about why computed enums are disabled for strings. Being able to use templated strings would be great. Looks like there was a similar issue here #20440. |
This would be handy when when writing a React component with a prop that controls a css class. Right now I'm doing the following enum ComponentVariant {
Foo,
Bar,
}
const classes = {
[ComponentVariant.Foo]: styles.fooClassName,
[ComponentVariant.Bar]: styles.barClassName,
}
export default function TheComponent({ variant }: {variant: ComponentVariant}) {
return <div className={classes[variant]} />
} But it would be both cleaner, and also safer (i.e. prevent accidentally indexing into a non-existing value in the classes object) to do this directly: enum ComponentVariant {
Foo = styles.fooClassName,
Bar = styles.barClassName,
}
export default function TheComponent({ variant }: {variant: ComponentVariant}) {
return <div className={variant} />
} |
Following the namespace reasoning, highly useful for developing browser extensions or other scripts where we don't want to collision with pre-existing scripts, such as |
I also need this |
Additionally symbols should be allowed to be used as enum values. enum MyType {
foo = Symbol("foo"), // Error: ts(18033) - Only numeric enums can have computed members, but this expression has type 'symbol'. If you do not need exhaustiveness checks, consider using an object literal instead.
} |
I'm with the same problem :/ |
please enable, thank you! |
Facing the same issue. I would love to have computed values for strings so I can assign react components to enums. |
PUSH!! i am currently facing this issue too.
as an example |
+1 |
I would love to have this on TS, thanks! |
This would be a great feature, currently running into this same issue |
I'm currently working to build a enum and interfaces in order to organize my database fields, finally as a custom orm system, and all my database fields have a prefix // current enum
enum MyTableFields {
OBJECT_ID = 'slot_objectID',
CODE = 'slot_code',
LABEL = 'slot_label'
// ...and many other fields
}
// wanted enum
const slot_ = 'slot_'
enum MyTableFields {
OBJECT_ID = `${slot_}objectID`,
CODE = `${slot_}code`,
LABEL = `${slot_}label`
} Apart from that this little formality, I wanted to explore another idea like handling schema or database table names inside enum, like this: // current enum
enum MyTableFields {
OBJECT_ID = 'database_name.schema.slot_objectID',
CODE = 'database_name.schema.slot_code',
LABEL = 'database_name.schema.slot_label'
// ...and many other fields
}
// wanted enum
const path = `${databaseName}.${schema}.slot_`
enum MyTableFields {
OBJECT_ID = `${path}objectID`,
CODE = `${path}code`,
LABEL = `${path}label`
} Enum with computed values could be helpfully helpful ! |
I too want to compute two enums with slight variations, such as a prefix. |
+1 here, would be great innovation |
+1 from me as well, I would like to assign values to enum variables depending on the environment via the ternary operator. |
I support this as well, any prospects for implementation horizon? |
+1, this would be quite helpful |
There's another error message you might get if you try this: |
This would be ideal! Especially when declaring API route constants. import { getExact } from "../../util/env";
enum ApiRoutes {
users = `${getExact('REACT_NATIVE_BACKEND_URL')}/****`,
blockUser = `${getExact('REACT_NATIVE_BACKEND_URL')}/****`,
reverifyUser = `${getExact('REACT_NATIVE_BACKEND_URL')}/****`,
resetPassword = `${getExact('REACT_NATIVE_BACKEND_URL')}/****`,
preferences = `${getExact('REACT_NATIVE_BACKEND_URL')}/****`,
pacemakers = `${getExact('REACT_NATIVE_BACKEND_URL')}/****`,
matchPreferences = `${getExact('REACT_NATIVE_BACKEND_URL')}/****`,
userLocation = `${getExact('REACT_NATIVE_BACKEND_URL')}/****`,
tokens = `${getExact('REACT_NATIVE_BACKEND_URL')}/****`,
messageThread = `${getExact('REACT_NATIVE_BACKEND_URL')}/****`,
readMessage = `${getExact('REACT_NATIVE_BACKEND_URL')}/****`,
suggestedSports = `${getExact('REACT_NATIVE_BACKEND_URL')}/****`,
suggestedGenders = `${getExact('REACT_NATIVE_BACKEND_URL')}/****`,
findMatch = `${getExact('REACT_NATIVE_BACKEND_URL')}/****`,
likeUser = `${getExact('REACT_NATIVE_BACKEND_URL')}/****`,
dislikeUser = `${getExact('REACT_NATIVE_BACKEND_URL')}/****`,
createP2pReferralCode = `${getExact('REACT_NATIVE_BACKEND_URL')}/****`,
p2pReferral = `${getExact('REACT_NATIVE_BACKEND_URL')}/****`,
citiesAPI = 'https://wft-geo-db.p.rapidapi.com/v1/geo/cities',
discover = `${getExact('REACT_NATIVE_BACKEND_URL')}/****`,
eventAttendance = `${getExact('REACT_NATIVE_BACKEND_URL')}/****`,
};
export default apiRoutes; |
I also need this feature |
+1 |
👋 Hi @ahejlsberg |
I'd love to have that feature too. |
Any update on this and the associated PR? |
Stay tuned... 😉 |
Now implemented in #50528. |
+1 |
2 similar comments
+1 |
+1 |
Why are people +1ing an implemented feature? |
Probably because people don't yet know of it? 🤷🏻♂️ I mean it's been implemented like a month ago only. |
Hey guys, how to fix this error? got this in playground (TS version: the latest Nightly):
and this in IntelliJ IDEA (TS version: 5.0.1-rc)
|
It's been a 4-5 months and still not included into latest release, wym. |
5.0 came out yesterday and includes this feature. |
I have a use case like this which still yields TS18033 on 5.0.4:
|
On 5.0.4 with angular this doesn't work:
|
@RyanCavanaugh this is still an issue even with TS 5.1.6: |
@RyanCavanaugh Could you please check what the cause of this problem is? |
The error message means what it says. |
I felt I should clarify... but I have the same question as @hanzheliva above. Since I personally think using hard-coded constant expressions (with operators in them) is a bit of a code stink. But I am curious as to how typescript evaluates what is a const expression and what isn't. Are we explicitly not allowed use conditional operators in the declaration of enums even when the expression iteself can be evaluated statically? |
Side Note: I've seen a couple examples of people trying to do the same with ternary expressions, but the key difference being that typescript still evaluates the following const foo = true ? 'x' : 'y'; as So for anyone curious, ternary expressions still won't work but at least it makes sense why. |
Issues with using one string enum in another seem like TS bugs; I reported a separate issue for this: Flagged code, for reference: enum E1 {
A = 'A',
}
const enums = {
E1,
};
enum E2 {
A = enums.E1.A,
} |
Search Terms
'TS18033', 'typescript define enum with constant string value', 'string enum computed constant'
Suggestion
Please consider enabling to use constant variables as values for string enums. The following code snippet fails compilation with TS18033 ('Only numeric enums can have computed members, but this expression has type 'string'. If you do not need exhaustiveness checks, consider using an object literal instead.')
, whereas the following passes:
Use Cases
Use string interpolation (templated strings) when defining the value of a string enum to be able to reuse pre-defined constants as part of the value. (E.g. namespace prefixes, extension postfixes)
Examples
Checklist
My suggestion meets these guidelines:
The text was updated successfully, but these errors were encountered: