我如何在编译时知道类型是否为枚举?

How can I know at compile-time whether a type is an enum?

我想编写一个函数来验证一个值是否是枚举的一部分,如果不是则抛出。来自 ,我写道:

    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(' / ')}`);
        }
    }

但是,我不喜欢 enumType 是 any。有没有我可以写的东西说“enumType 是一个枚举”?

不是,不是。

一旦编译,枚举就没有什么神奇之处了。它们只是具有字符串键和常量值的对象。该类型将是 Record<string, unknown>.

所以我认为这种类型和你要得到的一样紧:

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

如果您只想支持具有字符串值的枚举,那么您可以这样做:

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

但是没有办法区分枚举和这个:

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

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

如果您希望 testObj 成为类型错误,并且只允许使用 enum 关键字声明的枚举,那么我认为这是不可能的。

Playground