Skip to content

Unable to use enum with const modifier because of inline optimization #21391

Closed
@stieg

Description

@stieg

It seems there is a design shortcoming with const enum in TS because there is no way to get a list of all values without changing const enum to a plain old enum. This is a problem because there are cases where a developer would want to use a const enum but can not because they can not programatically get a list of all possible values (due to the inlining optimization).

In example suppose a developer wants to use a const enum to represent a field in a mongoose schema. Here is an example of what this code might look like:

const enum Sex {
  FEMALE = "Female",
  MALE = "Male",
}

interface IUser  {
  firstName: string,
  lastName: string,
  sex: Sex,
}

If this developer were to try and create a Mongoose schema, they would not be able to enforce strong types on this sex field they would fail because they would not have access to all the possible const enum values.

export const UserSchema: Schema = new Schema({
  firstName: String,
  lastName: String,
  sex: {
    enum: Object.values(Sex),   // Won't Work because Sex is optimized out.
    type: String,
  },
}, {});

The only way for me to get this to work is to remove the const declaration from the Sex enum. That is not what I want to do because I have no intention of adding additional Sex values to that enum. Thus this enum should be able to be declared as a const enum but can not be because of the aforementioned reasons. This seems like a bug or an oversight. What should be possible here is for me to call some special reserved property on the enum that will return a list of all keys for that enum. In example I would expect something like the following to work in the ideal scenario:

export const UserSchema: Schema = new Schema({
  firstName: String,
  lastName: String,
  sex: {
    enum: Sex._values,
    type: String,
  },
}, {});

This would allow me to use const enum types and also would allow me to know all possible values of the enum itself. Another way might be to add a special keyword like valuesof to get them. So in code it would look like valuesof Sex which would return the array ['Female', 'Male']. Thoughts?

Metadata

Metadata

Assignees

No one assigned

    Labels

    Working as IntendedThe behavior described is the intended behavior; this is not a bug

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions