diff --git a/src/enum.ts b/src/enum.ts index 174ecb4..0cf92c8 100644 --- a/src/enum.ts +++ b/src/enum.ts @@ -1,6 +1,6 @@ type NoUndefined = Exclude; -declare const enumDefinition: unique symbol; +declare const enumVariants: unique symbol; declare const enumMutable: unique symbol; const enumFactory = Symbol(); @@ -36,42 +36,43 @@ const enumFactory = Symbol(); * type Message = Enum>; * ``` */ -export type Enum = Readonly< - (unknown extends E ? {} +export type Enum = Readonly< + (unknown extends V + ? {} : { - [K in keyof E]: - & Record> - & Partial, K>, never>>; - }[keyof Sanitize]) & { - [enumDefinition]?: Sanitize; + [K in keyof V]: Record> & + Partial, K>, never>>; + }[keyof Sanitize]) & { + [enumVariants]?: Sanitize; [enumMutable]?: boolean; } >; -type Sanitize = Omit< - E, +type Sanitize = Omit< + V, | "_" | { - [K in keyof E]: NoUndefined extends never ? K : never; - }[keyof E] + [K in keyof V]: NoUndefined extends never ? K : never; + }[keyof V] >; -type EnumDefinition> = NoUndefined< - T[typeof enumDefinition] +type EnumVariants> = NoUndefined< + E[typeof enumVariants] >; -type EnumFactory = { - [K in keyof Sanitize]: E[K] extends null ? () => Enum - : (value: NoUndefined) => Enum; +type EnumFactory = { + [K in keyof Sanitize]: V[K] extends null + ? () => Enum + : (value: NoUndefined) => Enum; }; -type ExhaustiveMatcher = { - [K in keyof Sanitize]: (value: NoUndefined[K]>) => unknown; +type ExhaustiveMatcher = { + [K in keyof Sanitize]: (value: NoUndefined[K]>) => unknown; }; -type WildcardMatcher = Partial> & { _: () => unknown }; +type WildcardMatcher = Partial> & { _: () => unknown }; -export type Matcher = ExhaustiveMatcher | WildcardMatcher; +export type Matcher = ExhaustiveMatcher | WildcardMatcher; export function Variant(): T { return undefined as never; @@ -81,7 +82,7 @@ export class NonExhaustiveMatcherError extends Error { constructor() { super( "Non-exhaustive matcher. To ensure all possible cases are covered, you " + - "can add a wildcard `_` match arm.", + "can add a wildcard `_` match arm." ); } } @@ -120,21 +121,21 @@ export namespace Enum { * const quit = Message().Quit(null); * ``` */ - export function factory( - Enum: (new () => E) & { [enumFactory]?: EnumFactory }, - ): EnumFactory { + export function factory( + Enum: (new () => V) & { [enumFactory]?: EnumFactory } + ): EnumFactory { if (Enum[enumFactory] != null) return Enum[enumFactory]!; - const result: Partial> = {}; + const result: Partial> = {}; for (const variant in new Enum()) { // @ts-ignore result[variant] = ((value: any) => { - return { [variant]: value ?? null } as Enum; + return { [variant]: value ?? null } as Enum; }) as any; } - return (Enum[enumFactory] = result as EnumFactory); + return (Enum[enumFactory] = result as EnumFactory); } /** @@ -186,11 +187,11 @@ export namespace Enum { * ``` */ export function match< - T extends Enum, - M extends Matcher>, + E extends Enum, + M extends Matcher> >( - value: T, - matcher: M, + value: E, + matcher: M ): { [K in keyof M]: M[K] extends (arg: any) => any ? ReturnType : never; }[keyof M] { @@ -229,7 +230,7 @@ export namespace Enum { * // => { B: "Hello" } * ``` */ - export function mutate>(value: T, other: T): void { + export function mutate>(value: E, other: E): void { for (const variant in value) { // @ts-ignore delete value[variant];