How to cast object property value as an enum

Viewed 24

I have this enum

enum OfferType {
  Apartment = 'apartment',
  House = 'house',
  Room = 'room',
  Hotel = 'hotel',
}

Which of the options should be used, when you type the value of the property. When to apply each approach

1)

{
  type: type as OfferType
}
{
  type: OfferType[type as 'apartment' | 'house' | 'room' | 'hotel']
{
1 Answers

I'm going to assume that type is of type string because you're receiving it from something outside the scope of your TypeScript code.

In that case, I wouldn't use either option you've shown, because they both assume that type is a valid OfferType, and that's not a reliable assumption. (But if you want to make that assumption, there's no reason for #2, just use #1; playground link.)

Instead, I'd use either a type predicate function or a type assertion function, which both narrow the type of type to OfferType and check that assumption at runtime.

Type predicate:

function isOfferType(value: string): value is OfferType {
    return (Object.values(OfferType) as string[]).includes(value);
}

Usage:

if (isOfferType(type)) {
    obj = { type };
} else {
    // Handle the fact it isn't one

Playground link

Type assertion function:

function assertIsOfferType(value: string): asserts value is OfferType {
    if (!(Object.values(OfferType) as string[]).includes(value)) {
        throw new Error(`"${value}" is not a valid OfferType`);
    }
}

Usage:

assertIsOfferType(type);
const obj = { type };

Playground link

Related