Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the difference between enum and object in typescript

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.

like image 995
Florian Leitgeb Avatar asked Nov 17 '17 13:11

Florian Leitgeb


People also ask

Can an enum be an object TypeScript?

Enums or enumerations are a new data type supported in TypeScript. Most object-oriented languages like Java and C# use enums. This is now available in TypeScript too. In simple words, enums allow us to declare a set of named constants i.e. a collection of related values that can be numeric or string values.

What is an enum in TypeScript?

In TypeScript, enums, or enumerated types, are data structures of constant length that hold a set of constant values. Each of these constant values is known as a member of the enum. Enums are useful when setting properties or values that can only be a certain number of possible values.

What is difference between type and enum in TypeScript?

Enums allow us to define or declare a collection of related values that can be numbers or strings as a set of named constants. Unlike some of the types available in TypeScript, enums are preprocessed and are not tested at compile time or runtime.

Is enum a object?

Because an enum is technically a class, the enum values are technically objects. As objects, they can contain subroutines. One of the subroutines in every enum value is named ordinal(). When used with an enum value, it returns the ordinal number of the value in the list of values of the enum.


2 Answers

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";
like image 138
Fenton Avatar answered Oct 08 '22 01:10

Fenton


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';
like image 21
Martynas Skučas Avatar answered Oct 08 '22 02:10

Martynas Skučas