Skip to main content
Version: 3.0.0-dev 🔨

Catalog

A Catalog is a union of literal types. Use a catalog when needing to track which state some element is in, but no additional details. These maps of constants are most often used to store strings, but may also be used with numbers or booleans.

ts
const Suit = catalog(['Spades', 'Hearts', 'Clubs', 'Diamonds']);
const Suit: { Spades: "Spades"; Hearts: "Hearts"; Clubs: "Clubs"; Diamonds: "Diamonds"; }
type Suit = keyof typeof Suit;
type Suit = "Spades" | "Hearts" | "Clubs" | "Diamonds"
ts
const Suit = catalog(['Spades', 'Hearts', 'Clubs', 'Diamonds']);
const Suit: { Spades: "Spades"; Hearts: "Hearts"; Clubs: "Clubs"; Diamonds: "Diamonds"; }
type Suit = keyof typeof Suit;
type Suit = "Spades" | "Hearts" | "Clubs" | "Diamonds"

In this scenario, catalog is quite similar to the strEnum function users may be familiar with.

Numbers​

ts
const logLevels = catalog({
trace: 100,
debug: 200,
info: 300,
warn: 400,
error: 500,
fatal: 600,
})
ts
const logLevels = catalog({
trace: 100,
debug: 200,
info: 300,
warn: 400,
error: 500,
fatal: 600,
})

catalog() will enforce that all values are of the same type, ensuring that a stray '600' will raise an error.

Programmatic values​

The values of the literals can be defined programmatiocally. For example, the logLevels values follow a strict formula—the index times 100. Catalog allows us to express this programmatically.

ts
const logLevels = catalog(
['trace', 'debug', 'info', 'warn', 'error', 'fatal'],
(_, i) => (i+1) * 100
);
ts
const logLevels = catalog(
['trace', 'debug', 'info', 'warn', 'error', 'fatal'],
(_, i) => (i+1) * 100
);

This version of the code can be shorter and is often more resilient against refactoring.

Matching Catalogs​

In order to streamline domain-modeling, literal unions (such as those from catalog()) may be directly processed through match() and matcher().

ts
const animal = catalog(['cat', 'dog', 'snake']);
type animal = keyof typeof animal;
 
const fittingPokemon = (a: animal) => match(a, {
cat: _ => 'Meowth',
dog: _ => 'Arcanine',
snake: _ => 'Ekans',
})
ts
const animal = catalog(['cat', 'dog', 'snake']);
type animal = keyof typeof animal;
 
const fittingPokemon = (a: animal) => match(a, {
cat: _ => 'Meowth',
dog: _ => 'Arcanine',
snake: _ => 'Ekans',
})

Other library functions can be accessed by elevating the literal union to a full discriminated union through ofLiteral().