Anwesh Budhathoki
Anwesh Budhathoki

Reputation: 121

Object values to Enum or type

I have a object as :

const bodyParts: Record<string, string>  = {
  HAND: 'hand',
  MOUTH: 'mouth'
}

I have used the object later as

type PartType = "hand"| "mouth"

const data: Array<{part: 'hand' | 'mouth'}> = [{
  part: bodyParts[HAND]
}, {
  part: bodyParts[MOUTH]
}
]

But I want to extract PartType from values of bodyParts. Is there any walkaround for this? Or maybe to create enum from object and set type as enum. I tried looking for creating enum but didnot got to solution. I can create Enum but I want to automate task of creation of enum, as bodyparts can be added.

Upvotes: 0

Views: 40

Answers (1)

T.J. Crowder
T.J. Crowder

Reputation: 1074495

I suspect with a broader understanding of your end goal, one could suggest a better alternative to the use of bodyParts as shown in the question, but you can do what you want to do by inferring the type from the constant, like this:

const bodyParts: Record<string, string> = {
    HAND: "hand",
    MOUTH: "mouth",
};

const data: Array<{ part: typeof bodyParts[keyof typeof bodyParts] }> = [
    {
        part: bodyParts.HAND,
    },
    {
        part: bodyParts.MOUTH,
    },
];

playground link

Or it's a bit clearer if we grab an alias for typeof bodyParts:

const bodyParts: Record<string, string> = {
    HAND: "hand",
    MOUTH: "mouth",
};
type BodyParts = typeof bodyParts;

const data: Array<{ part: BodyParts[keyof BodyParts] }> = [
    {
        part: bodyParts.HAND,
    },
    {
        part: bodyParts.MOUTH,
    },
];

playground link

But, if you want to preserve the compile-time type of those (and in particular to ensure that data is a tuple, not just an array), you may do better with const assertions and less explicit typing:

const bodyParts = {
    HAND: "hand",
    MOUTH: "mouth",
} as const;

const data = [
    {
        part: bodyParts.HAND,
    },
    {
        part: bodyParts.MOUTH,
    },
] as const;

playground link

Upvotes: 1

Related Questions