SeyyedKhandon
SeyyedKhandon

Reputation: 6133

How to de-structure an enum values in typescript?

I have an enum in typescript like below:

export enum XMPPElementName {
  state = "state",
  presence = "presence",
  iq = "iq",
  unreadCount = "uc",
  otherUserUnreadCount = "ouc",
  sequenceID = "si",
  lastSequenceID = "lsi",
  timeStamp = "t",
  body = "body",
  message = "message"
}

And wants to de-structure its value, How can we do this in Typescript?

const { uc, ouc, msg, lsi, si, t, body } =  XMPPElementName; 

update

As @amadan mentioned, we can use Assigning to new variable names as in Mozilla doc say Destructuring_assignment, like below:

Assigning to new variable names

A property can be unpacked from an object and assigned to a variable with a different name than the object property.

const o = {p: 42, q: true};
const {p: foo, q: bar} = o;
 
console.log(foo); // 42 
console.log(bar); // true

And the method is very good to solve this problem, but if you need to access all items without the need to explicitly define them, you can either on of these two mentiond tag1 tag2

Upvotes: 6

Views: 6300

Answers (4)

kmars
kmars

Reputation: 164

This may be helpful for anyone looking for a quick and easy answer - yes you can (at least as of now). This works for enums with and without assigned values as far as I can tell.

enum MyEnum {
  One,
  Two,
  Three
}

const { One, Two, Three } = myEnum;

console.log({ One, Two, Three }) // {One: 0, Two: 1, Three: 2}

enum Status {
   None = '',
   Created = 'CREATED',
   Completed = 'COMPLETED',
   Failed = 'FAILED',
}

const { None, Created, Completed, Failed } = Status;

console.log(None, Created, Completed, Failed) // '', 'CREATED', 'COMPLETED, 'FAILED'

Please write me back if I'm wrong or you found any weirdness when testing yourself.

Upvotes: 0

hackape
hackape

Reputation: 19987

You want an enum value-to-value map. Like you've said enum in JS is just a POJO. You can create a utility type to help generate the correct type.

type EnumValueMap<T extends { [k: string]: string }> = { [K in T[keyof T]]: K }

function convertEnumValuesToObject<T extends { [k: string]: string }>(enumerable: T): EnumValueMap<T> {
  return (Object as any).fromEntries(Object.values(enumerable).map(v => [v, v]))
}

Playground Link

Upvotes: 2

Amadan
Amadan

Reputation: 198436

const { uc, ouc, msg, lsi, si, t, body } =  XMPPElementName; 

This doesn't work because XMPPElementName doesn't have an element named uc (and equivalently for others). If you explicitly name your keys, it will work:

  const {
    unreadCount: uc,
    otherUserUnreadCount: ouc,
    message: msg,
    lastSequenceID: lsi,
    sequenceID: si,
    timeStamp: t,
    body: body,
  } = XMPPElementName;

it will work. Alternately, you can just use variables with names that are equal to the keys, not the values:

  const {
    unreadCount,
    otherUserUnreadCount,
    message,
    lastSequenceID,
    sequenceID,
    timeStamp,
    body,
  } = XMPPElementName;

Upvotes: 7

SeyyedKhandon
SeyyedKhandon

Reputation: 6133

As we know, in typescript an enum is like a plain old javascript object(at-least what the playground js-output is showing or the log showing):

enter image description here

one way is using a function which generates a new object with {value:value} structure like below:

export function convertEnumValuesToObject<T>(enumObj: T): { [index: string]: T[keyof T] } {
  const enum_values = Object.values(enumObj);
  return Object.assign({}, ...enum_values.map(_ => ({ [_]: _ })));
}

  const { uc, ouc, msg, lsi, si, t, body } = convertEnumValuesToObject(
      XMPPElementName
    ); 

It would be great to see answers in typescript?

Upvotes: 1

Related Questions