10
enum Direction {
    Up = 1,
    Down,
    Left,
    Right
}

if (typeof Direction === 'enum') {
    // doesn't work
}

Any way to check if the above is in fact an enum?

2
  • Why do you want to check if it's an enum? What do you mean by "check"--check at run-time? But enums are a compile-time construct. Commented Feb 2, 2017 at 16:32
  • Check before compile time. As to why: I want to convert the object to an array and want to know whether I need to remove half the object's properties. I was wondering if there was a very clean way to know if the object is of this type of data structure before attempting the conversion. Commented Feb 2, 2017 at 16:35

2 Answers 2

7

Enums are compiled into simple objects that have two way mapping:

name => value
value => name

So the enum in your example compiles to:

var Direction;
(function (Direction) {
    Direction[Direction["Up"] = 1] = "Up";
    Direction[Direction["Down"] = 2] = "Down";
    Direction[Direction["Left"] = 3] = "Left";
    Direction[Direction["Right"] = 4] = "Right";
})(Direction || (Direction = {}));

So the typeof of Direction is a plain "object".
There's no way of knowing in runtime that the object is an enum, not without adding more fields to said object.


Edit

Sometimes you don't need to try to workaround a problem with a specific approach you have, you can maybe just change the approach.
In this case, you can use your own object:

interface Direction {
    Up: 1,
    Down: 2,
    Left: 3,
    Right: 4
}
const Direction = {
    Up: 1,
    Down: 2,
    Left: 3,
    Right: 4
} as Direction;

Or:

type Direction = { [name: string]: number };
const Direction = { ... } as Direction;

Then turning this object into an array should be simple.

Sign up to request clarification or add additional context in comments.

12 Comments

RIght. But is there a way to detect before compile time? Is there a way that typescript might detect such a thing?
I suppose it might be possible to write a function that would inspect the compiled object's properties for their symmetry.
Can you please add an example to your question for the use case you have in mind? I fail to see how that can be beneficial.
I want to write a function that will convert the object to an array but if it's an enum also remove half its properties.
Yeah, I understood that part. But if you use this as your enum then you won't need to make that distinction to begin with because then your function could just convert it without worrying about removing half the props
|
3

For the record, here's a method that will determine if an object is an enum:

  isEnum(instance: Object): boolean {
    let keys = Object.keys(instance);
    let values = [];

    for (let key of keys) {
      let value = instance[key];

      if (typeof value === 'number') {
        value = value.toString();
      }

      values.push(value);
    }

    for (let key of keys) {
      if (values.indexOf(key) < 0) {
        return false;
      }
    }

    return true;
  }

3 Comments

it accepts null in its current state, but other than that, very useful, thank you!
This is quite a slow operation just to get a trivial type.
This does not work with string enums because they are not reverse mapped: typescriptlang.org/docs/handbook/release-notes/…

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.