#DRY for Union Types

11 messages · Page 1 of 1 (latest)

compact ibex
#

Consider a type declaration like:

type PackageManagers = 'pnpm' | 'yarn' | 'npm'

Later, I need to provide a list of options as a string array like: ['pnpm', 'yarn', 'npm']
I don't like this repetition -- is there an expression that creates the list of values from the type (or vice versa)?
(I guess I'm thinking along the lines of an Java Enum.values.)

Additionally, consider that I have a map like:

const commands = {
  pnpm: "pnpm do something",
  yarn: "yarn do something",
  npm: "npm do something"
}

And then a new Package Manager option like bun is added. Is there a way to flag commands because it is incomplete because it is missing a bun element?

plain wraith
#

Create the array first and use as const on it

#

That will create a tuple which will be your source of truth

#

Then you can get back the union using typeof yourArray[number]

#

And for the commands object, use a Record type

#
const packageManagers = ["npm", "pnpm", "yarn"] as const;

type PackageManager = typeof packageManagers[number];

const commands: Record<PackageManager, string> = { ... }
plain wraith
#

@compact ibex

compact ibex
#

You are smarter than Copilot.

Can you please explain to me what the number is doing here?

type PackageManagers = typeof packageManagers[number];

plain wraith
#

When you use number, it is like using all possible numeric index on that array/tuple type, which gives the union of values

compact ibex