enumwaii

API essentials

Create declarations, choose member views, parse input, compose sets, and derive exhaustive data.

The base API gives a closed string set an owner, validates unknown input, and carries member identity through TypeScript.

Create a declaration

import {  } from "enumwaii";

const  = (["DRAFT", "READY", "ARCHIVED"]);
const  = .;
type  = (typeof )["~type"];

The values tuple must be non-empty. Duplicate values are removed in first-seen order, including values introduced by extend or em.combine.

When API-facing keys need to differ from canonical wire values, use the object overload:

import {  } from "enumwaii";

const  = ({
  : "order-paid",
  : "order-pending",
});
const  = .;

.; // branded "order-paid"
.("order-paid");

This is an escape hatch; prefer tuple declarations when keys and values can be identical. Object keys are the developer-facing names on .enum, .rawEnum, and .cases. The mapped values are canonical everywhere else, including identity, parsing, Standard Schema, adapters, iteration, and derivation. Object declarations must be non-empty and cannot contain duplicate values.

The object form is also the supported way to attach member-level JSDoc. TypeScript preserves documentation from named object properties on the corresponding .enum properties, but its type system does not carry comments from tuple elements into generated property symbols:

import {  } from "enumwaii";

const  = ({
  /** Default state when no workflow is active. */
  : "NONE",
  /** Work is currently in progress. */
  : "ACTIVE",
});

..;

When no-object-em is enabled, every property must have JSDoc for a documentation-only identity mapping to be accepted. Partially documented or undocumented redundant objects are still reported.

Surface map

SurfaceUse it for
enumNamed, branded application members. This is the default.
valuesIterating branded members.
rawEnumNamed unbranded values for integration APIs that cannot accept branded types.
rawValuesAn unbranded tuple for schema, database, or provider metadata.
casesNative discriminated-union tags when TypeScript cannot narrow a branded string.
~typeThe branded member union, available only to TypeScript.
~keysThe raw value union for Record and satisfies, available only to TypeScript.
~safeParseResultThis declaration's discriminated parse result, available only to TypeScript.
~standardThe Standard Schema v1 contract.

.enum, .rawEnum, and .cases are referentially the same frozen object at runtime, but their static types serve different jobs. Extract each view before using its members; the type-aware lint preset can enforce that convention.

Validate values

.(); // type guard
.(); // State or EnumwaiiParseError
.(); // success/failure result

Both parse methods accept { default, fallback }. default covers only null and undefined; fallback covers every otherwise-invalid input.

Members are strings at runtime and serialize directly through JSON, URLs, form data, database drivers, and structured cloning.

Compose declarations

const  = .([., .]);
const  = .([.]);
const  = .(["DELETED"]);

const  = (["LOW", "HIGH"]);
const  = .([, ]);

pick and omit retain the source identity and any surviving aliased keys. extend retains the source identity while widening its domain; new tuple members use identity keys where key equals value. combine derives a new identity from the complete combined value set and exposes identity keys because input keys are declaration-local cosmetics.

Derive exhaustive data

const  = .(
  [., "Draft"],
  [., "Ready"],
  [., "Archived"],
);

.(.);
..;

Tuple entries preserve source-member provenance in a way object keys cannot. Use states.derive<Metadata>()(...) to contextually type every entry once, callback derivation for uniform transforms, and deriveTo when every output must belong to another declaration.

Type utilities

Prefer declaration-local utilities when the declaration is already in scope:

type  = (typeof )["~type"];
type  = (typeof )["~keys"];
type  = (typeof )["~safeParseResult"];

const  = {
  : "Draft",
  : "Ready",
  : "Archived",
} as  satisfies <, string>;

InferEnumwaii<T> and InferEnumwaiiCase<T> are also exported for generic or cross-module code where naming the declaration-local properties is less useful. See the generated API reference for every exported signature, class member, error property, and type parameter.

On this page