feat: add Result type

This commit is contained in:
Lukas Obermann
2024-12-16 13:38:15 +01:00
parent fe64105602
commit 19b619b768
2 changed files with 95 additions and 0 deletions
+95
View File
@@ -0,0 +1,95 @@
/**
* A result is either a value or an error.
*/
export type Result<T, E> = Ok<T> | Error<E>
/**
* A result that contains a value.
*/
export interface Ok<T> {
readonly tag: "Ok"
readonly value: T
}
/**
* A result that contains an error.
*/
export interface Error<E> {
readonly tag: "Error"
readonly error: E
}
/**
* Creates a result that contains a value.
*/
export const ok = <T>(value: T): Result<T, never> => ({ tag: "Ok", value })
/**
* Checks if a result contains a value.
*/
export const isOk = <T, E>(result: Result<T, E>): result is Ok<T> =>
result.tag === "Ok"
/**
* Creates a result that contains an error.
*/
export const error = <E>(error: E): Result<never, E> => ({
tag: "Error",
error,
})
/**
* Checks if a result contains an error.
*/
export const isError = <T, E>(result: Result<T, E>): result is Error<E> =>
result.tag === "Error"
/**
* Reduces a result to a value of a common type.
*/
export const reduce = <T, E, R>(
result: Result<T, E>,
fok: (value: T) => R,
ferror: (error: E) => R
): R => (isOk(result) ? fok(result.value) : ferror(result.error))
/**
* Maps the value of a result to a new value.
*/
export const map = <T, U, E>(
result: Result<T, E>,
f: (value: T) => U
): Result<U, E> => (isOk(result) ? ok(f(result.value)) : result)
/**
* Maps an error to a new error.
*/
export const mapError = <T, E, F>(
result: Result<T, E>,
f: (value: E) => F
): Result<T, F> => (isError(result) ? error(f(result.error)) : result)
export const combine = <T1, T2, TR, E1, E2, ER>(
result1: Result<T1, E1>,
result2: Result<T2, E2>,
fok: (value1: T1, value2: T2) => TR,
ferror: (error1: E1, error2: E2) => ER
): Result<TR, E1 | E2 | ER> =>
isOk(result1)
? isOk(result2)
? ok(fok(result1.value, result2.value))
: result2
: isOk(result2)
? result1
: error(ferror(result1.error, result2.error))
export const Result = Object.freeze({
ok,
isOk,
error,
isError,
reduce,
map,
mapError,
combine,
})
View File