Skip to content

unacy / createRegistry

Function: createRegistry()

ts
function createRegistry<Edges>(): UnitRegistry<Edges extends readonly E[] ? E[] : never> & UnitMap<Edges>;

Defined in: packages/core/src/registry.ts:713

Create a new, empty converter registry.

The factory entry point for unacy. Returns an empty UnitRegistry that can be grown incrementally via chained .register() calls. Each call produces a new registry instance with an expanded type signature reflecting the new edge.

Type Parameters

Type ParameterDefault typeDescription
Edges extends readonly Edge<any, any>[][]Optional tuple of Edge types to pre-declare available units and conversions before register() calls (rarely needed in practice).

Returns

UnitRegistry<Edges extends readonly E[] ? E[] : never> & UnitMap<Edges>

Empty converter registry with full type-safe unit accessor support

Example

typescript
import { createRegistry, type WithUnits, type BaseMetadata } from 'unacy';

const CelsiusMeta = { name: 'Celsius' as const, symbol: '°C' } satisfies BaseMetadata;
const FahrenheitMeta = { name: 'Fahrenheit' as const, symbol: '°F' } satisfies BaseMetadata;
const KelvinMeta = { name: 'Kelvin' as const, symbol: 'K' } satisfies BaseMetadata;

type Celsius = WithUnits<number, typeof CelsiusMeta>;
type Fahrenheit = WithUnits<number, typeof FahrenheitMeta>;
type Kelvin = WithUnits<number, typeof KelvinMeta>;

const registry = createRegistry()
  .register(CelsiusMeta, FahrenheitMeta, { to: c => (c * 9/5) + 32, from: f => (f - 32) * 5/9 })
  .register(CelsiusMeta, KelvinMeta, c => c + 273.15)
  .allow(KelvinMeta, FahrenheitMeta); // lift BFS-composed path into types

const f = registry.Celsius.to.Fahrenheit(25 as Celsius); // 77
const k = registry.Celsius.to.Kelvin(0 as Celsius);      // 273.15

Use When

You need a type-safe, composable unit conversion graph for a domain. The primary entry point for all unacy usage.

Avoid When

You only need a single direct conversion with no type guarantees — a plain function is lighter and requires no registry setup overhead.

Pitfalls

NEVER reassign a registry variable without capturing the register() return value — each call returns a new instance; the original is unchanged.

typescript
// WRONG — result is discarded
const r = createRegistry();
r.register(CelsiusMeta, FahrenheitMeta, converter); // r is not updated

// CORRECT — chain the calls
const registry = createRegistry()
  .register(CelsiusMeta, FahrenheitMeta, converter);

NEVER add values of different units directly in arithmetic — the type system prevents this at compile time, but if you bypass it with as, the runtime will silently produce incorrect results with no error.

NEVER use as to cast a Quantity<Celsius> to Quantity<Fahrenheit> — this defeats the entire purpose of the phantom type system.

See

  • UnitRegistry
  • UnitMap

Released under the MIT License.