UNPKG

ts-data-forge

Version:

[![npm version](https://img.shields.io/npm/v/ts-data-forge.svg)](https://www.npmjs.com/package/ts-data-forge) [![npm downloads](https://img.shields.io/npm/dm/ts-data-forge.svg)](https://www.npmjs.com/package/ts-data-forge) [![License](https://img.shields.

79 lines 3.48 kB
/** * Type-safe pattern matching function for string-based discriminated unions. * * Provides compile-time guarantees for exhaustive case handling when working * with literal string unions. Automatically enforces completeness checking when * all cases are covered, and requires a default value when cases are * incomplete. * * ## Key Features: * * - **Exhaustive Matching**: When all cases of a literal union are handled, no * default value is needed * - **Partial Matching**: When cases are incomplete or working with general * string types, a default value is required * - **Type Safety**: Prevents extra cases and ensures only valid keys are used * - **Strict Property Checking**: Rejects objects with unexpected properties * * @example * * ```ts * type Status = 'draft' | 'review' | 'published'; * * const status: Status = 'draft'; * * const message = match< * Status, * { draft: string; review: string; published: string } * >(status, { * draft: 'Work in progress', * review: 'Awaiting feedback', * published: 'Complete', * }); * * assert.isTrue(message === 'Work in progress'); * ``` * * @param target - The value to match against * @param cases - Object mapping possible values to their corresponding results * @param defaultValue - Fallback value (required when not all cases are * covered) * @returns The matched result or default value */ export declare function match<const Case extends string, const R extends ReadonlyRecord<Case, unknown>>(target: Case, cases: StrictPropertyCheck<R, Case>): R[Case]; export declare function match<const Case extends string, const R extends UnknownRecord, const D>(target: Case, cases: StrictPropertyCheck<R, Case>, defaultValue: IsLiteralUnionFullyCovered<Case, R> extends true ? never : D): ValueOf<R> | D; /** * @template T The object type to check. * @template ExpectedKeys The union of string literal types representing the * allowed keys. * @internal * Helper type to ensure that an object `T` only contains keys specified in `ExpectedKeys`. * If `T` has any keys not in `ExpectedKeys`, this type resolves to `never`. */ type StrictPropertyCheck<T, ExpectedKeys extends PropertyKey> = RelaxedExclude<keyof T, ExpectedKeys> extends never ? T : never; /** * @template Case A union of string literal types representing the possible * cases. * @template R A record type. * @internal * Helper type to check if all cases in `Case` union are fully covered by keys in `R`. * This checks bidirectional coverage: all Case members are in R, and no extra keys. */ type AllCasesCovered<Case extends PropertyKey, R> = TypeEq<Case, keyof R> extends true ? true : false; /** * @template Case A union of string literal types. * @template R A record type. * @internal * Helper type to check if Case is a literal union type and all cases are covered. */ type IsLiteralUnionFullyCovered<Case extends PropertyKey, R extends UnknownRecord> = TypeEq<IsLiteralType<Case>, true> extends true ? AllCasesCovered<Case, R> : false; /** * @template T The PropertyKey type to check. * @returns `true` if `T` is a literal type, `false` otherwise. * @internal * Helper type to determine if a given PropertyKey `T` is a literal type (e.g., 'a', 1) * or a general type (e.g., string, number). */ type IsLiteralType<T extends PropertyKey> = string extends T ? false : number extends T ? false : symbol extends T ? false : true; export {}; //# sourceMappingURL=match.d.mts.map