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