What is the difference between enum and object in typescript

JavascriptTypescriptObjectEnums

Javascript Problem Overview


I am trying to access values of a map via enum and also make a translation ready app for all the strings in it. Both concerns overlap and I have to decide between using enums or just object in JSON format.

So what exactly is the difference and useage between an enum and an object?

For example:

  • I can use enums to access arrays as well as inserting labels and other stuff like

const enum FieldNames { FirstField: "Field One", SecondField: "Field Two" };

someFieldArray[FieldNames.FirstField].label = FieldNames.FirstField; someFieldArray[FieldNames.SecondField].label = FieldNames.SecondField;

  • Or I can achieve the same behaviour via object

const FieldNames = {
  FirstField: "Field One",
  SecondField: "Field Two"
};

someFieldArray[FieldNames.FirstField].label = FieldNames.FirstField;
someFieldArray[FieldNames.SecondField].label = FieldNames.SecondField;

I really do not get the benefit choosing enums over simple objects. In my opinion an object has much more benefits without any downsides.

Javascript Solutions


Solution 1 - Javascript

Enum

An enum may give you additional benefits, if you want the features:

const enum FieldNamesEnum {
  FirstField = "Field One",
  SecondField = "Field Two"
};

let x: FieldNamesEnum;

x = FieldNamesEnum.FirstField;
x = FieldNamesEnum.SecondField;

// Error - not assignable to FieldNames
x = 'str';

// Cannot assign
FieldNamesEnum.FirstField = 'str';

Importantly, you can't assign to the enum members and types are checked to the enum members, rather than string.

Additionally, because you have used a const enum in your example, the enum won't exist at runtime and all the references will be substituted for the literal values (if you used a plain enum the enum would exist at runtime).

Object

Compare this to the object example:

const FieldNames = {
  FirstField: "Field One",
  SecondField: "Field Two"
};

let y: string;

y = FieldNames.FirstField;
y = FieldNames.SecondField;

// Oops it works
y = 'str';

// Oops it works

FieldNames.FirstField = 'str';

Union

If you don't need the full enum, but want to limit the values, you can use a union of literal values:

type FieldNames = "Field One" | "Field Two";

let x: FieldNames;

x = "Field One";
x = "Field Two";

// Error - not allowed
x = "Field Three";

Solution 2 - Javascript

I don't aggre with @Fenton. Objects are the type safe.

const FieldNames = {
  FirstField: 'Field One',
  SecondField: 'Field Two',
} as const;

type ValueOf<T> = T[keyof T];
let y: ValueOf<typeof FieldNames>;

y = FieldNames.FirstField;
y = FieldNames.SecondField;

// TS2322: Type '"str"' is not assignable to type '"Field One" | "Field Two"'.
y = 'str';

// TS2540: Cannot assign to 'FirstField' because it is a read-only property
FieldNames.FirstField = 'str';

Solution 3 - Javascript

function (foo: FieldNames) { }

If FieldNames is an object, this means this function expects an instance which has the properties FirstField and SecondField. If FieldNames is an enum (in which case it should be singular, not plural), this means the function expects one of the values of FieldNames, namely "Field One" or "Field Two".

Very different usage.

Solution 4 - Javascript

In the Typescript language handbook, you have a dedicated section talking about that: Objects vs Enums.

Personally, when I need a type with a set of options, I prefer using Typescript enum, because it is easier to use. With the enum definition, you have the type and also the way to access the options. To implement the same aproach with an object, you need to define the object as const and also define an extra type based on it.

Solution 5 - Javascript

this should be main reason.. you can use enum as a type so one of following options, but you cant define cosnt object as a type, it will have all options in one obj :)

you can also do this

type FieldNames = "Field One" | "Field Two";

but if list is long, enum is much better, in ES6 enum is pure useless just use obejct but in typescript its a type and its a main benefit in my opition

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionFlorian LeitgebView Question on Stackoverflow
Solution 1 - JavascriptFentonView Answer on Stackoverflow
Solution 2 - JavascriptMartynas SkučasView Answer on Stackoverflow
Solution 3 - JavascriptdecezeView Answer on Stackoverflow
Solution 4 - JavascriptJosé Antonio PostigoView Answer on Stackoverflow
Solution 5 - JavascriptVladislav GuleaevView Answer on Stackoverflow