dan_kaufhold
dan_kaufhold

Reputation: 647

How can I create union-like or enum-like behaviour from string constants in TypeScript?

I currently have a list of constants holding color values:

const gray = "#555"
const grayLight = "#777"
const primary1 = "#fff"
const primary2 = "#000"

I also have a function which receives arguments in the form of an object for which I want to create an interface. One of the arguments should be a subset of these colors.

Here is an example how this would look using a union type.

interface props {
  argument1: string
  colorChoices: '#555' | '#777'
}
function myFunction(props: props): void {
  //...
}

I know that enums and union types don't accept computed (string) values by design. So the following does not work:

const gray = "#555"
const grayLight = "#777"
enum colors {
  gray = gray,
  grayLight = grayLight,
}
type grays = gray | grayLight

I could come up with the following example, which would make it type safe and would make it work, but the constant duplication does not seem like a sensible pattern.

type gray = '#555'
const gray: gray = '#555'
type grayLight = '#777'
const grayLight: grayLight = '#777'
type grayScale = gray | grayLight

interface props {
  argument1: string
  colorChoices: grayScale
}
function myFunction(props: props): void {
  //...
}

Is there a way to achieve this behaviour without duplicating my constant values and have the values in one place only?

Upvotes: 3

Views: 35

Answers (1)

Titian Cernicova-Dragomir
Titian Cernicova-Dragomir

Reputation: 250336

You can use typeof on constant to get the actual type of the constant so you don't need to define the type for each constant:

const gray = '#555'
const grayLight = '#777'
type grayScale = typeof gray | typeof grayLigh

Upvotes: 3

Related Questions