KoenT_X
KoenT_X

Reputation: 329

How to know if incoming variable is of a specific enum type?

I have a class that has an overloaded constructor, where an input argument can be either a number, an instance of a certain class type, or a value of certain enum type:

class Person { name: string; };
enum PersonType { Type1, Type2 };

constructor(id: number);
constructor(person: Person);
constructor(personType: PersonType);
constructor(arg: string | Person | PersonType)
{
    if (typeof arg === "number") { /* do number stuff */ }
    else if (arg instanceof Person) { /* do Person stuff */ }
    else if (typeof arg === "PersonType") { /* do PersonType stuff */ }
    else throw new MyException("...");
}

Now, apparently, when I execute the "typeof arg" in case an enum value is supplied, that evaluates to "number", and not "PersonType", so my code can't work as expected. Using instanceof for an enum type doesn't work either, as it's meant for object types only.

So, can anyone tell me how I can get to know when my input argument is of a specific enum type? What am i missing here?

Upvotes: 18

Views: 10692

Answers (3)

user7375303
user7375303

Reputation:

This is kind of wrokaround you can use:

enum PersonType { Type1 = 'Type1', Type2 = 'Type2' }

To test if the incoming arg string is of type PersonType, you can use this check:

if (Object.values(PersonType).includes(arg)) {...}

This check returns true if arg == 'Type1' or 'Type2' and can also support any new added entries to the enum since we are looping on all possible values of the ennum

Upvotes: 0

Dolan
Dolan

Reputation: 1647

It is possible with string enums

You can declare an enum like so:

export enum PageNumber {
    CURRENT = "CURRENT",
    TOTAL_PAGES = "TOTAL_PAGES ",
    TOTAL_PAGES_IN_SECTION = "TOTAL_PAGES_IN_SECTION ",
}

Then you can check it against string:

if (typeof child === "string") {

Intelli-sense seems to not flag errors

enter image description here

It also seems to be aware of the enum type too:

enter image description here

Upvotes: -2

Paleo
Paleo

Reputation: 23692

So, can anyone tell me how I can get to know when my input argument is of a specific enum type?

It's not possible. Look at the compiled code for the enum:

TypeScript:

enum PersonType { Type1, Type2 }

JavaScript:

var PersonType;
(function (PersonType) {
    PersonType[PersonType["Type1"] = 0] = "Type1";
    PersonType[PersonType["Type2"] = 1] = "Type2";
})(PersonType || (PersonType = {}));

At runtime, the enum PersonType is just a JavaScript object used as a map. Its members are strings and numbers. The enumeration of your example contains:

{
  "Type1": 0,
  "Type2": 1,
  "0": "Type1",
  "1": "Type2"
}

So, the members Type1 and Type2 in the enumeration, are true numbers:

console.log(PersonType.Type1) // 0

Upvotes: 11

Related Questions