Skip to content

Instantly share code, notes, and snippets.

@madyanalj
Last active April 19, 2022 16:36
Show Gist options
  • Save madyanalj/f1cbd06e1214801ee82065b91ad80af2 to your computer and use it in GitHub Desktop.
Save madyanalj/f1cbd06e1214801ee82065b91ad80af2 to your computer and use it in GitHub Desktop.
TypeScript Enums vs Literal Unions

Enum Pros

  • native TS langugae server (which IDEs use by default) supports jumping to usages of enum keys (pretty sure it's possible to do this with unions using extensions/JetBrains, but it's not built-in into vscode at the moment)
  • more familiar (as it's used in many programming languages)

Literal Union Pros

  • could be easily extended:
    type UkCity = "london" | "edinburgh"
    type SupportedCIty = UkCity | "dublin"
  • More concise
    enum AllowedCities {
      london = 'london'
      edinburgh = 'edinburgh'
    }
    // vs
    type AllowedCities = 'london' | 'edinburgh'
    
    const isAllowedCity = (c) => Object.values(AllowedCities).includes(c)
    // vs
    const isAllowedCity = (c) => AllowedCities.includes(c)
    
    import { AllowedCities } from '...'
    findVendors(AllowedCities.edinburgh)
    // vs
    findVendors('edinburgh') // no need to import
  • Could be derived from bigger objects:
    const SUPPORTED_CITIES = {
      london: {
        phone: "+44......',
        currency: "GBP",
      },
      dublin: {
        phone: "....",
        currency: "EUR",
      },
    } as const
    
    type SupportedCities = typeof SUPPORTED_CITIES
    
    // derive type of allowed cities without declaring them again
    type SupportedCity = keyof SupportedCities // "london" | "dublin"
    
    // derive type of allowed currencies without declaring them again
    type SupportedCurrency = SupportedCities[SupportedCity]["currency"] // "GBP" | "EUR"
  • Could be used with other unions where the type are the same, whilist enums can't:
    // these two enums will always have same values
    enum CitiesX { London }
    enum CitiesY { London }
    
    const doSomething = (c: CitiesX) => ...
    // will error even though the keys/values of the two enums are compatible with each other
    doSomething(CitiesY.London)
    This is an issue when we have no control where an enum comes from (e.g. we have an enum auto-generated by graphql codegen and a helper with a matching enum declared in an npm package)
  • Less typing when using e.g. 'lon<auto-complete> vs Ci<auto-complete>.<auto-complete> (plus need to (auto)import)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment