Skip to content

Instantly share code, notes, and snippets.

@YBogomolov
Last active November 10, 2023 15:19
Show Gist options
  • Save YBogomolov/78296c4dc048435ab6d1d39e52de6b45 to your computer and use it in GitHub Desktop.
Save YBogomolov/78296c4dc048435ab6d1d39e52de6b45 to your computer and use it in GitHub Desktop.
import { either } from 'fp-ts';
import { pipe } from 'fp-ts/function';
import Either = either.Either;
declare global {
interface ErrorConstructor<T extends string = string> extends Error<T> {}
interface Error<T extends string = string> {
readonly tag: T;
new<T extends string>(message?: string): Error<T>;
}
}
export const catchSome = <E extends E1, A, E1 extends Error<string>>(
handle: ((error: E) => A),
guard: ((e: E1) => e is E)
) => (ea: Either<E1, A>): Either<Exclude<E1, E>, A> => pipe(
ea,
either.match(
e1 => guard(e1) ? either.right(handle(e1)) : either.left(e1 as Exclude<E1, E>),
either.right,
)
);
class A extends Error<'A'> { public readonly tag = 'A'; }
class B extends Error<'B'> { public readonly tag = 'B'; }
class C extends Error<'C'> { public readonly tag = 'C'; }
class D extends Error<'D'> { public readonly tag = 'D'; }
type Errors = A | B | C | D;
declare const eeee: Either<Errors, string>;
const result: Either<B | C | D, string> = pipe(
eeee,
catchSome(
error => error.message,
(error: Errors): error is A => error instanceof A,
)
);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment