Home > front end >  How can I know at compile-time whether a type is an enum?
How can I know at compile-time whether a type is an enum?

Time:02-24

I want to write a function that validates that a value is part of an enum, and throw if not. From this answer, I wrote:

    private ensureValueInEnum(enumType: any, value: string): void {
        if (!Object.values(enumType).includes(value)) {
            throw new Exception(`${value} is invalid value. Valid values are: ${Object.values(enumType).join(' / ')}`);
        }
    }

But, I don't like that enumType is any. Is there something I can write that says "enumType is an enum"?

CodePudding user response:

Not really, no.

Once compiled, there's nothing magic about enums. They are just objects with string keys and constant values. That type would be Record<string, unknown>.

So I think this type is as tight as your going to get:

function ensureValueInEnum(enumType: Record<string, unknown>, value: unknown): void {
  //
}

If you only want to support enums with string values, then you could do:

function ensureValueInEnum(enumType: Record<string, string>, value: string): void {
  //
}

But there no way to distinguish an enum from, say, this:

const testObj = {
    C: 'c',
    D: 'd',
}

ensureValueInEnum(testObj, 'c') // works
ensureValueInEnum(testObj, 'q') // error

If you want testObj to be a type error, and only enums declared with the enum keyword to be allowed, then I don't think that's possible.

Playground

  • Related