Carlton
Carlton

Reputation: 679

Create Typescript Type from Enum values

I'm looking for a way to create a Typescript type from ENUM values. Currently I'm having to manually construct the type and keep it in sync with the ENUM.

Is there a way to create a type as a oneof from ENUM values? End result being when I update the ENUM the type will automatically reflect it

enum FRUITS {
    APPLE = 'apple',
    PEAR = 'pear',
    ORANGE = 'orange',
}

// type Fruits = FRUITS;
type Fruits = 'apple' | 'pear' | 'orange';

// This works
const fruit: Fruits = FRUITS.APPLE;
// This also works
const fruit2: Fruits = 'apple';

The type will be used in these scenarios so both have to still work:

const fruit: Fruits = FRUITS.APPLE;

const fruit2: Fruits = 'apple';

Upvotes: 1

Views: 667

Answers (1)

jcalz
jcalz

Reputation: 330571

I always recommend staying away from enum unless the values are truly opaque, meaning you do not need any TS code outside the enum declaration to refer to the number/string as literal values. (Actually I tend to stay away from numeric enum entirely, since all number values are assignable to them, see microsoft/TypeScript#17734 among other issues)

For the specific use cases presented in your example, I'd be inclined to drop enum and use a strongly-typed enumlike object instead:

const FRUITS = {
  APPLE: 'apple',
  PEAR: 'pear',
  ORANGE: 'orange',
} as const;

That allows Fruits to be defined programmatically:

type Fruits = typeof FRUITS[keyof typeof FRUITS];

And then everything in your example still works:

const fruit: Fruits = FRUITS.APPLE;
const fruit2: Fruits = 'apple';

Playground link to code

Upvotes: 6

Related Questions