What is the difference between enum and object in typescript

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';

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.


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";