8

Hello im trying t develop a straight forward todo app using TypeScript and JQuery. I have an enum that lists task types:

export enum TaskType { FrontEnd, BackEnd, Designer };

However looping through the emum using jquery.each or for loop, i get the following result, (values then indexes):

        FrontEnd, BackEnd, Designer, 0, 1, 2

The following is the code i loop through the enum:

        constructor(e?: Object) {             

            var template = this.FormTemplate;

            $(e).append(template);

            var sel = template.find('select');

            /*$.each(TaskType, function (index, el) {
                sel.append("<option value='" + index + "'>" + el + "</option>");
            });*/

            for(var i=0; i < (typeof TaskType).length; i++){
                sel.append("<option value='" + TaskType[i] + "'>" + TaskType[i] + "</option>");
            }

        }

Can someone tell me why this is?

meji
  • 1,041
  • 3
  • 11
  • 12
  • Possible duplicate of [How does one get the names of TypeScript enum entries?](https://stackoverflow.com/questions/18111657/how-does-one-get-the-names-of-typescript-enum-entries) – jjbskir Apr 04 '19 at 15:51

1 Answers1

20

TypeScript enums when compiled into plain JS contain both the symbolic name AND the numeric values as properties and that explains why you get FrontEnd, BackEnd, Designer, 0, 1, 2 when you try to enumerate the properties of the object. As best I know, there is no post-compile way to enumerate only the symbolic names. You could enumerate all of them and skip anything that is a number.

From this article, you can see exactly how a TypeScript enum compiles into JS.

If you have this TypeScript:

//TypeScript declaration:
enum StandardEnum {FirstItem, SecondItem, ThirdItem};

It compiles to this Javscript:

//Compiled javascript:
var StandardEnum;
(function (StandardEnum) {
    StandardEnum[StandardEnum["FirstItem"] = 0] = "FirstItem";
    StandardEnum[StandardEnum["SecondItem"] = 1] = "SecondItem";
    StandardEnum[StandardEnum["ThirdItem"] = 2] = "ThirdItem";
})(StandardEnum || (StandardEnum = {}));
;

Which is essentially this result:

var StandardEnum = {
    "FirstItem": 0,
    "SecondItem": 1,
    "ThirdItem": 2,
    "0": "FirstItem",
    "1": "SecondItem",
    "2": "ThirdItem"
};

So, unless you specifically ignore the numeric properties, there is no way to enumerate just the enum names.

You could do that like this:

 for (var item in StandardEnum) {
     if (StandardEnum.hasOwnProperty(item) && !/^\d+$/.test(item)) {
         console.log(item);
     }
 }

Working demo: http://jsfiddle.net/jfriend00/65cfg88u/


FYI, if what you really want is:

var StandardEnum = {
    "FirstItem": 0,
    "SecondItem": 1,
    "ThirdItem": 2
};

Then, maybe you should not use the enum and just use this standard JS declaration. Then, you could get the properties with Object.keys(StandardEnum).

jfriend00
  • 683,504
  • 96
  • 985
  • 979
  • Thanks for the explanation but wouldn't it make sense to return it as key:value object?, this is a big let down, anyway i ended up using : if(TaskType[i] !== undefined) in for loop since it returns values then undefined values. – meji Jun 04 '15 at 21:38
  • 1
    @meji - you can return whatever you want - I was just showing you how you could identify only the named properties. FYI, maybe you should just define a JS object with properties rather than an enum if that's what you want it to be. – jfriend00 Jun 04 '15 at 21:41
  • Does this also apply for typescript@2? – k0pernikus Jan 09 '17 at 15:26
  • @k0pernikus - I don't have any reason to believe it has changed in TS2.0, but have not explicitly examined TS2.0 output in this regard. – jfriend00 Jan 09 '17 at 18:02
  • How about something like `Object.values(myEnum).filter(isNaN)` to get an array of non-number values? – Shahar 'Dawn' Or Mar 25 '17 at 16:58
  • 1
    @mightyiam - It's possible that would work for this specific case, but it could depend upon what the enum values were because of special cases. I don't like relying on automatic type coercion and the coercion rules for `isNan()` are quite complicated [see here](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/isNaN#Description). – jfriend00 Mar 25 '17 at 21:27