UNPKG

wellcrafted

Version:

Delightful TypeScript patterns for elegant, type-safe applications

47 lines (45 loc) 2.34 kB
import { Err } from "./result-_socO0Ud.js"; //#region src/error/types.d.ts /** * Base type for any tagged error, used as a minimum constraint. */ type AnyTaggedError = { name: string; message: string; }; /** * Constructor return must include `message: string`. * JSON serializability is a convention, not enforced at the type level * (optional fields produce `T | undefined` which breaks `JsonObject`). */ type ErrorBody = { message: string; }; /** * Per-key validation: tells the user exactly what `name` will be stamped as. * * `name` is stamped by the factory itself (`{ name: K } & ReturnType<fn>`); * a user-provided `name` would be silently overwritten, so we error loudly. */ type ValidateErrorBody<K extends string> = { message: string; name?: `The 'name' key is reserved as '${K}'. Remove it.`; }; /** The config: each key is a variant name, each value is a constructor function. */ type ErrorsConfig = Record<string, (...args: any[]) => ErrorBody>; /** Validates each config entry, injecting the key-specific `name` reservation message. */ type ValidatedConfig<T extends ErrorsConfig> = { [K in keyof T & string]: T[K] extends ((...args: infer A) => infer R) ? (...args: A) => R & ValidateErrorBody<K> : T[K] }; /** Single factory: takes constructor args, returns Err-wrapped error. */ type ErrorFactory<TName extends string, TFn extends (...args: any[]) => ErrorBody> = { [K in TName]: (...args: Parameters<TFn>) => Err<Readonly<{ name: TName; } & ReturnType<TFn>>> }; type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends ((k: infer I) => void) ? I : never; /** Return type of `defineErrors`. Maps each config key to its factory. */ type DefineErrorsReturn<TConfig extends ErrorsConfig> = UnionToIntersection<{ [K in keyof TConfig & string]: ErrorFactory<K, TConfig[K]> }[keyof TConfig & string]>; /** Extract the error type from a single factory. */ type InferError<T> = T extends ((...args: any[]) => Err<infer R>) ? R : never; /** Extract union of ALL error types from a defineErrors return. */ type InferErrors<T> = { [K in keyof T]: T[K] extends ((...args: any[]) => Err<infer R>) ? R : never }[keyof T]; //#endregion export { AnyTaggedError, DefineErrorsReturn, ErrorBody, ErrorsConfig, InferError, InferErrors, ValidatedConfig }; //# sourceMappingURL=types-ojNaDB4n.d.ts.map