Mohrn
Mohrn

Reputation: 816

Can you get the keys from an enum based on it's type?

I got a generic class where one of it's generic parameters is an enum. Is it possible to get the keys of the enum based on the generic parameter?

A simplified example:

abstract class Foo<T> {
    protected abstract myEnumValues: T[];

    getEnumKeys() {
      // Can I get the string representation of the keys of T here?
      // I can get them from MyEnum
      console.log(Object.keys(MyEnum)
        .filter(isNaN));
      // And I can use T's keys for typing
      let x: {
        [keys in keyof T]: any
      };
    }
}

enum MyEnum {
    KeyA = 1,
    KeyB = 2,
    KeyC = 3
}

class Bar extends Foo<MyEnum> {
    protected myEnumValues: MyEnum[] = [MyEnum.KeyA, MyEnum.KeyB];
} 

const bar = new Bar();
bar.getEnumKeys();

https://codepen.io/a-morn/pen/ZEzKjxK

Upvotes: 0

Views: 189

Answers (2)

Valeriy Katkov
Valeriy Katkov

Reputation: 40732

No, you cannot, at compile time no type information is available. But, you can pass the enum object to the class, so it will be available at runtime, like:

abstract class Foo<T> {
    protected abstract myEnumValues: ReadonlyArray<T[keyof T]>;

    constructor(private readonly enumObj: T) {}

    getEnumKeys(): ReadonlyArray<keyof T> {
        return Object
            .keys(this.enumObj)
            .filter(key => isNaN(Number(key)))
            .map(key => key as keyof T);
    }
}

enum MyEnum {
    KeyA = 1,
    KeyB = 2,
    KeyC = 3
}

class Bar extends Foo<typeof MyEnum> {
    protected myEnumValues = [MyEnum.KeyA, MyEnum.KeyB];

    constructor() {
        super(MyEnum);
    }
}

const bar = new Bar();

Upvotes: 1

niQu
niQu

Reputation: 341

No, generic parameters are only available on compile time for type checking. But to solve your problem you could pass the enum into your base class and read your info out of that type.

Upvotes: 0

Related Questions