2

I have an enum

export enums Actions {
All = 1,
Success = 2,
Failed = 3
}

When I iterate through it using for loop, I am getting total of 6 entries. I get to know that this is how it works in Typescript. But how can I use the enum so that I can access

enum.key 

for "All, Success, Falied" and

enum.value 

for 1,2,3

6 Answers 6

2

As per the docs of typescript, if as const keyword suffices, then we dont need to use enum.

Just interpreting, maybe in this case an implementation like illustrated can be used, with Object.keys(obj) and Object.values(obj) to get the required outputs

const Actions = {
  All: 0,
  Success: 1,
  Failure: 2
} as const

let keyArr = Object.keys(Actions);
let valArr = Object.values(Actions);
Sign up to request clarification or add additional context in comments.

Comments

2

What you can do in order to access the enum keys and values like you described in the OP is convert your enum to a basic object that has the properties keys and values with the corresponding data.

export enum Actions {
  All = 1,
  Success = 2,
  Failed = 3
}

export type ConvertedActions = {
  keys: string[];
  values: Actions[];
};

const result = Object.values(Actions).reduce(
  (acc, curr): ConvertedActions =>
    isNaN(+curr)
      ? {...acc, keys: [...acc.keys, curr as string]}
      : {...acc, values: [...acc.values, curr as Actions]},
  <ConvertedActions>{keys: [], values: []}
);

console.log(result.keys);    // [ 'All', 'Success', 'Failed' ]
console.log(result.values);  // [ 1, 2, 3 ]

Note: Don't get confused by the extra type (ConvertedActions) I defined. However, it is needed to avoid using any a lot.

Comments

1
const keys = Object.keys(Actions);
const values = Object.values(Actions);

Comments

1

This is what I came up with and I think it's as intuitive as it's gonna get

for (const keyString in Actions) {
    const key = Number(keyString);
    if (isNaN(key)) { continue; }
    console.log(key);
}

1 Comment

An explanation always imp[roves a code-only answer.
0

What you can do, in this specific case, is separating All, Success, Falied and 1, 2, 3 in two different arrays.

export enums Actions {
    All = 1,
    Success = 2,
    Failed = 3
}
console.log(Object.keys(enums).filter((v) => isNaN(Number(v)))); // ["All", "Success", "Failed"] 
console.log(Object.keys(enums).filter((v) => !isNaN(Number(v)))); // ["1", "2", "3"]

You can also do it with a for..in loop:

for (const value in enums) {
  console.log(value); // 1, 2, 3, All, Success, Falied
  console.log(value.filter((v) => isNaN(Number(v)))); // All, Success, Falied
  console.log(value.filter((v) => !isNaN(Number(v)))); // 1, 2, 3
}

There are more ways to do it using forEach, for..of, etc. But from your question I think my example should do the trick.

Comments

0

A simpler and type-safe solution may be the following:

/** Type that accept enumerations. */
type Enum = { [k: string]: (number | string) };

type EnumIteratorCallback<T> = (value: T, key?: string) => void;

function enumIterator<T>(e: Enum, callback: EnumIteratorCallback<T>): void {
    const keys = Object.keys(e).filter(k => isNaN(Number(k)));
    for (const key of keys) {
        callback(e[key] as T, key);
    }
}

This way the callback receive exactly the enumeration type. key parameter is optional.

Usage examples:

enum NumericEnum {
    Zero,
    One,
    Two,
}

enum StringsEnum {
    First = "first",
    Second = "second",
    Third = "third",
}

enum MixedEnum {
    First = 1,
    Second = "second",
    Third = 3,
}

console.log("NumericEnum:");
enumIterator<NumericEnum>(NumericEnum, (value: NumericEnum, key?: string): void => {
    console.log(`${key} -> ${value}`);
});

console.log("StringsEnum:");
enumIterator<StringsEnum>(StringsEnum, (value: StringsEnum, key?: string): void => {
    console.log(`${key} -> ${value}`);
});

console.log("MixedEnum:");
enumIterator<MixedEnum>(MixedEnum, (value: MixedEnum, key?: string): void => {
    console.log(`${key} -> ${value}`);
});

Playground example

Comments

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.