Starting with Typescript 3.4 , you can use a combination of keyof typeof
and const
statements to create objects that can have the same type safety as enumerations, and yet contain complex values.
By creating type
with the same name as const
, you can have the same exhaustibility checks as regular enums.
The only problem is that you need some key in a complex object (here I use value
) to store the name of the enum member (if someone can figure out a helper function that can create these objects in a safe way, I would like to see this ! I could not get to work).
export const PizzaSize = { small: { value: 'small', key: 0, size: 25 }, medium: { value: 'medium', key: 1, size: 35 }, large: { value: 'large', key: 2, size: 50 }, } as const export type PizzaSize = keyof typeof PizzaSize // if you remove any of these cases, the function won't compile // because it can't guarantee that you've returned a string export function order(p: PizzaSize): string { switch (p) { case PizzaSize.small.value: return 'just for show' case PizzaSize.medium.value: return 'just for show' case PizzaSize.large.value: return 'just for show' } } // you can also just hardcode the strings, // they'll be type checked export function order(p: PizzaSize): string { switch (p) { case 'small': return 'just for show' case 'medium': return 'just for show' case 'large': return 'just for show' } }
In other files this can be used simply, just import PizzaSize
.
import { PizzaSize } from './pizza' console.log(PizzaSize.small.key) type Order = { size: PizzaSize, person: string }
Also note that even objects that are usually mutable cannot be modified using the as const
syntax.
const Thing = { ONE: { one: [1, 2, 3] } } as const
source share