typescript enums vs unions

Typescript enums have their uses but are extra hassle when creating new dto instances. I don't think enums are a good fit for working with dtos. 

When I try to instantiate a new AutoTagsConfigType instance as mock data for tests, typescript is reporting an error for the status field because it's defined as an ATStatus enum

So setting status to a literal like this is not acceptable to typescript

const mockData: AutoTagsConfigType =  {
   status: 'Pending',

   id: 'd3f963fb-2201-4f5c-ae38-21bf22cec001',
   name: 'Big Spender',
}

but setting status as: status: ATStatus.Pending does work

however that's not very nice to have to do (use the enum type all the time, I prefer using literals)
especially if typescript has another way of achieving the same goal (limit status values) using unions

if ATStatus is a union not an enum, then setting values literally works as we would like and typescript will only allow set one of those values
type ATStatus = 'Ready' | 'Pending' | 'Onboarding' | 'Disabled';

So union makes more sense to me.

Having said that, here's something to consider which combines best of both worlds

  1. define the enum as before: 
    1. export enum ATStatus { Ready = 'Ready', Pending = 'Pending', Onboarding = 'Onboarding', Disabled = 'Disabled', }
  2. use keyof typeof to create a new union type: 
    1. type ATStatusOther = keyof typeof ATStatus;
  3. use ATStatusOther as the status field type: status: ATStatusOther
  4. and now you can set literal values on the status field status: 'Pending'.
  5. OR set using the enum status: ATStatus.Ready (wow!)

That's cool syntactic sugar and gets us what we want....but why not just use the union since simpler and more obvious.

warning: keyof typeof only picks up the value of the enum name so if initialized to different value then it won't work (in ATStatus case the name of the enum values and the actual literal value are the same so it works).

Comments

Popular posts from this blog

deep dive into Material UI TextField built by mui

angular js protractor e2e cheatsheet

react-router v6.4+ loaders, actions, forms and more