resultable
Version:
A small package to handle errors as values
116 lines (110 loc) • 8.06 kB
text/typescript
/**
* Describes the match object, where the keys are the discriminant ids, and the values
* are the functions which handle the value
*/
type MakeMatchObj<D extends string, ADT extends Record<D, string>, Z> = {
[K in ADT[D]]: (v: MakeADTMember<D, ADT, K>) => Z;
};
/**
* Unions all the return types of matcher functions
*/
type MakeReturns<D extends string, ADT extends Record<D, string>, M extends MakeMatchObj<D, ADT, unknown>> = {
[K in keyof M]: ReturnType<M[K]>;
}[keyof M];
/**
* Helper type for extracting a member from an ADT
*/
type MakeADTMember<D extends string, ADT, Type extends string> = Extract<ADT, Record<D, Type>>;
declare function makeMatchI<D extends string>(d: D): <ADT extends Record<D, string>>(v: ADT) => <M extends MakeMatchObj<D, ADT, unknown>>(matchObj: M) => MakeReturns<D, ADT, M>;
declare const matchBrand: <ADT extends Record<"__brand", string>>(v: ADT) => <M extends MakeMatchObj<"__brand", ADT, unknown>>(matchObj: M) => MakeReturns<"__brand", ADT, M>;
type match_MakeADTMember<D extends string, ADT, Type extends string> = MakeADTMember<D, ADT, Type>;
type match_MakeMatchObj<D extends string, ADT extends Record<D, string>, Z> = MakeMatchObj<D, ADT, Z>;
type match_MakeReturns<D extends string, ADT extends Record<D, string>, M extends MakeMatchObj<D, ADT, unknown>> = MakeReturns<D, ADT, M>;
declare const match_makeMatchI: typeof makeMatchI;
declare const match_matchBrand: typeof matchBrand;
declare namespace match {
export { type match_MakeADTMember as MakeADTMember, type match_MakeMatchObj as MakeMatchObj, type match_MakeReturns as MakeReturns, match_makeMatchI as makeMatchI, match_matchBrand as matchBrand };
}
type Equals<X, Y> = (<T>() => T extends X ? 1 : 2) extends <T>() => T extends Y ? 1 : 2 ? true : false;
declare const TypeId: unique symbol;
type TypeId = typeof TypeId;
type BaseError<T extends string> = Error & {
readonly [TypeId]: TypeId;
readonly __brand: T;
};
declare function BrandedError<T extends string>(brand: T): new <Args extends Record<string, any> = {}>(args: Equals<Args, {}> extends true ? void : {
readonly [P in keyof Args as P extends "__brand" ? never : P]: Args[P];
}) => BaseError<T> & Args;
declare const UnknownException_base: new <Args extends Record<string, any> = {}>(args: Equals<Args, {}> extends true ? void : { readonly [P in keyof Args as P extends "__brand" ? never : P]: Args[P]; }) => Error & {
readonly __brand: "@Shared/UnknownException";
readonly [TypeId]: TypeId;
} & Args;
declare class UnknownException extends UnknownException_base<{
message?: string;
cause?: unknown;
}> {
constructor(args?: {
message?: string;
cause?: unknown;
});
}
type OkResult<T> = Readonly<[value: T, error: undefined]>;
type ErrorResult<E extends BaseError<string>> = Readonly<[
value: undefined,
error: E
]>;
type Result<T, E extends BaseError<string>> = OkResult<T> | ErrorResult<E>;
type ExtractOk<T> = T extends OkResult<infer U> ? U : never;
type ExtractErr<T> = T extends ErrorResult<infer E> ? E : never;
type MergeResults<TUnion extends OkResult<any> | ErrorResult<any>> = ExtractErr<TUnion> extends never ? OkResult<ExtractOk<TUnion>> : ExtractOk<TUnion> extends never ? ErrorResult<ExtractErr<TUnion>> : Result<ExtractOk<TUnion>, ExtractErr<TUnion>>;
type NormalizeResult<R> = R extends OkResult<infer T> ? R : R extends ErrorResult<infer E> ? R : R extends BaseError<infer E> ? ErrorResult<R> : never;
declare const resultableFn: <Params extends any[], TUnion extends OkResult<any> | ErrorResult<BaseError<string>> | BaseError<string>>(fn: (...args: Params) => Promise<TUnion>) => ((...args: Params) => Promise<MergeResults<NormalizeResult<TUnion>>>);
declare function ok<T>(value: T): OkResult<T>;
declare function err<E extends BaseError<any>>(error: E): ErrorResult<E>;
declare function okVoid(): OkResult<void>;
declare function fail(args?: ConstructorParameters<typeof UnknownException>[0]): ErrorResult<UnknownException>;
declare function tryCatch<T>(fn: () => Promise<T>): Promise<Result<T, UnknownException>>;
declare function tryCatch<T, E extends BaseError<string>>(fn: () => Promise<T>, errorFn: (cause: unknown) => E): Promise<Result<T, E>>;
type Mapper<T, R> = (value: T) => R;
declare function map<T, E extends BaseError<string>, R>(mapper: Mapper<T, R>): (result: Result<T, E>) => Result<R, E>;
declare function map<T, E extends BaseError<string>, R>(result: Result<T, E>, mapper: Mapper<T, R>): Result<R, E>;
declare function mapErr<T, E extends BaseError<string>, R extends BaseError<string>>(mapper: Mapper<E, R>): (result: Result<T, E>) => Result<T, R>;
declare function mapErr<T, E extends BaseError<string>, R extends BaseError<string>>(result: Result<T, E>, mapper: Mapper<E, R>): Result<T, R>;
declare function catchAllErr<T, E extends BaseError<string>, R>(mapper: Mapper<E, R>): (result: Result<T, E>) => OkResult<R>;
declare function catchAllErr<T, E extends BaseError<string>, R>(result: Result<T, E>, mapper: Mapper<E, R>): OkResult<R>;
type InferBrand<E extends BaseError<string>> = E extends BaseError<infer B> ? B : never;
declare function catchAllBrands<T, E extends BaseError<string>, R, MatchObject extends MakeMatchObj<"__brand", E, R>, R2 extends ReturnType<MatchObject[InferBrand<E>]>>(brandMatchers: MatchObject): (result: Result<T, E>) => OkResult<T | R2>;
declare function catchAllBrands<T, E extends BaseError<string>, R, MatchObject extends MakeMatchObj<"__brand", E, R>, R2 extends ReturnType<MatchObject[InferBrand<E>]>>(result: Result<T, E>, brandMatchers: MatchObject): OkResult<T | R2>;
declare function unwrap<T>(result: OkResult<T>): T;
declare function unwrapErr<E extends BaseError<string>>(result: ErrorResult<E>): E;
declare function isErr<T, E extends BaseError<string>>(result: Result<T, E>): result is ErrorResult<E>;
declare function isBrandedError(value: unknown): value is BaseError<any>;
declare function exhaustiveSwitchGuard(_: never): never;
type result_BaseError<T extends string> = BaseError<T>;
declare const result_BrandedError: typeof BrandedError;
type result_ErrorResult<E extends BaseError<string>> = ErrorResult<E>;
type result_MergeResults<TUnion extends OkResult<any> | ErrorResult<any>> = MergeResults<TUnion>;
type result_OkResult<T> = OkResult<T>;
type result_Result<T, E extends BaseError<string>> = Result<T, E>;
type result_TypeId = TypeId;
type result_UnknownException = UnknownException;
declare const result_UnknownException: typeof UnknownException;
declare const result_catchAllBrands: typeof catchAllBrands;
declare const result_catchAllErr: typeof catchAllErr;
declare const result_err: typeof err;
declare const result_exhaustiveSwitchGuard: typeof exhaustiveSwitchGuard;
declare const result_fail: typeof fail;
declare const result_isBrandedError: typeof isBrandedError;
declare const result_isErr: typeof isErr;
declare const result_map: typeof map;
declare const result_mapErr: typeof mapErr;
declare const result_ok: typeof ok;
declare const result_okVoid: typeof okVoid;
declare const result_resultableFn: typeof resultableFn;
declare const result_tryCatch: typeof tryCatch;
declare const result_unwrap: typeof unwrap;
declare const result_unwrapErr: typeof unwrapErr;
declare namespace result {
export { type result_BaseError as BaseError, result_BrandedError as BrandedError, type result_ErrorResult as ErrorResult, type result_MergeResults as MergeResults, type result_OkResult as OkResult, type result_Result as Result, type result_TypeId as TypeId, result_UnknownException as UnknownException, result_catchAllBrands as catchAllBrands, result_catchAllErr as catchAllErr, result_err as err, result_exhaustiveSwitchGuard as exhaustiveSwitchGuard, result_fail as fail, result_isBrandedError as isBrandedError, result_isErr as isErr, result_map as map, result_mapErr as mapErr, result_ok as ok, result_okVoid as okVoid, result_resultableFn as resultableFn, result_tryCatch as tryCatch, result_unwrap as unwrap, result_unwrapErr as unwrapErr };
}
export { match as Match, result as Result, TypeId };