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
| Surface | Use it for |
|---|---|
enum | Named, branded application members. This is the default. |
values | Iterating branded members. |
rawEnum | Named unbranded values for integration APIs that cannot accept branded types. |
rawValues | An unbranded tuple for schema, database, or provider metadata. |
cases | Native discriminated-union tags when TypeScript cannot narrow a branded string. |
~type | The branded member union, available only to TypeScript. |
~keys | The raw value union for Record and satisfies, available only to TypeScript. |
~safeParseResult | This declaration's discriminated parse result, available only to TypeScript. |
~standard | The 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 resultBoth 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.