From a91005f2736b5969f684aeeb9945ff05b1b1c1b5 Mon Sep 17 00:00:00 2001 From: bkiac Date: Fri, 3 Nov 2023 21:49:37 +0100 Subject: [PATCH 1/7] Fix missing test --- src/helpers/fn.test.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/helpers/fn.test.ts b/src/helpers/fn.test.ts index d5c10e7..fa24b8a 100644 --- a/src/helpers/fn.test.ts +++ b/src/helpers/fn.test.ts @@ -21,4 +21,10 @@ describe.concurrent("asyncFn", () => { const result = await wrappedFn() expect(result.unwrap()).toEqual(42) }) + + it("returns Err result when provided async function returns Err", async () => { + const wrappedFn = asyncFn(async () => Promise.resolve(Err("rekt"))) + const result = await wrappedFn() + expect(result.unwrapErr()).toEqual("rekt") + }) }) From 0f4bb0a2bce3c019ee7f0ed976aa70f263bc7666 Mon Sep 17 00:00:00 2001 From: bkiac Date: Fri, 3 Nov 2023 22:01:16 +0100 Subject: [PATCH 2/7] Add result variants --- src/result/err.ts | 5 ++--- src/result/interface.ts | 18 +++++++++++++++++- src/result/ok.ts | 7 +++---- 3 files changed, 22 insertions(+), 8 deletions(-) diff --git a/src/result/err.ts b/src/result/err.ts index 0423f28..ee59f4a 100644 --- a/src/result/err.ts +++ b/src/result/err.ts @@ -1,11 +1,10 @@ import {Panic, UnwrapPanic} from "../error/panic" import {inspectSymbol} from "../util" -import type {Result, ResultMethods} from "./interface" +import type {ErrVariant, Result, ResultMethods} from "./interface" import type {Ok} from "./ok" -export class ErrImpl implements ResultMethods { +export class ErrImpl implements ErrVariant, ResultMethods { readonly ok = false - readonly value?: never readonly err = true readonly error: E diff --git a/src/result/interface.ts b/src/result/interface.ts index 6916801..f215739 100644 --- a/src/result/interface.ts +++ b/src/result/interface.ts @@ -34,4 +34,20 @@ export interface ResultMethods { toJSON(): {meta: "Ok"; data: T} | {meta: "Err"; data: E} } -export type Result = Ok | Err +export type OkVariant = { + readonly ok: true + readonly err: false + readonly value: T +} + +export type ErrVariant = { + readonly ok: false + readonly err: true + readonly error: E +} + +export type ResultVariants = OkVariant | ErrVariant + +export type Result = ResultVariants & ResultMethods + +const wtf = {} as Result diff --git a/src/result/ok.ts b/src/result/ok.ts index 74bb70d..55c6cac 100644 --- a/src/result/ok.ts +++ b/src/result/ok.ts @@ -1,13 +1,12 @@ import {Panic, UnwrapPanic} from "../error/panic" import {inspectSymbol} from "../util" import type {Err} from "./err" -import type {Result, ResultMethods} from "./interface" +import type {OkVariant, Result, ResultMethods} from "./interface" -export class OkImpl implements ResultMethods { +export class OkImpl implements OkVariant, ResultMethods { readonly ok = true - readonly value: T readonly err = false - readonly error?: never + readonly value: T constructor(value: T) { this.value = value From 0db42844f9209e5a3fc88b84ba735cb9420449ab Mon Sep 17 00:00:00 2001 From: bkiac Date: Fri, 3 Nov 2023 22:20:52 +0100 Subject: [PATCH 3/7] Remove dummy type --- src/result/interface.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/result/interface.ts b/src/result/interface.ts index f215739..9532983 100644 --- a/src/result/interface.ts +++ b/src/result/interface.ts @@ -49,5 +49,3 @@ export type ErrVariant = { export type ResultVariants = OkVariant | ErrVariant export type Result = ResultVariants & ResultMethods - -const wtf = {} as Result From 2b01c9cebfd3182fc6b50e9a846665dc93203974 Mon Sep 17 00:00:00 2001 From: bkiac Date: Fri, 3 Nov 2023 22:25:20 +0100 Subject: [PATCH 4/7] Fix type errors with fn and asyncFn --- src/helpers/fn.ts | 13 ++++++++----- src/helpers/try.ts | 4 ++-- src/util.ts | 30 +++++++++++------------------- 3 files changed, 21 insertions(+), 26 deletions(-) diff --git a/src/helpers/fn.ts b/src/helpers/fn.ts index d3024c3..241f679 100644 --- a/src/helpers/fn.ts +++ b/src/helpers/fn.ts @@ -1,4 +1,9 @@ -import type {ResultValueType, ResultErrorType} from "../util" +import type { + ResultValueType, + ResultErrorType, + AsyncResultValueType, + AsyncResultErrorType, +} from "../util" import type {Result} from "../result/interface" import {PromiseResult} from "../result/promise" @@ -9,9 +14,7 @@ export function fn Result>( } export function asyncFn Promise>>(f: T) { - return function ( - ...args: Parameters - ): PromiseResult>, ResultErrorType>> { - return new PromiseResult(f(...args)) + return function (...args: Parameters) { + return new PromiseResult, AsyncResultErrorType>(f(...args)) } } diff --git a/src/helpers/try.ts b/src/helpers/try.ts index ded9842..be5b14b 100644 --- a/src/helpers/try.ts +++ b/src/helpers/try.ts @@ -1,5 +1,5 @@ import {Panic} from "../error/panic" -import {type ErrorHandler, type ResultError, type StdError, toStdError} from "../error/result_error" +import {type ErrorHandler, type ResultError, StdError, toStdError} from "../error/result_error" import {Err} from "../result/err" import type {Result} from "../result/interface" import {Ok} from "../result/ok" @@ -35,7 +35,7 @@ export function tryFnWith( } export function tryPromise(promise: Promise): PromiseResult { - return new PromiseResult( + return new PromiseResult( promise.then( (value) => Ok(value), (error: unknown) => Err(toStdError(error)), diff --git a/src/util.ts b/src/util.ts index 511dd73..4d7548e 100644 --- a/src/util.ts +++ b/src/util.ts @@ -1,28 +1,20 @@ -import type {Option} from "./option/interface" -import type {PromiseOption} from "./option/promise" -import type {Result} from "./result/interface" -import type {PromiseResult} from "./result/promise" +import type {Err} from "./result/err" +import type {Ok} from "./result/ok" export const inspectSymbol = Symbol.for("nodejs.util.inspect.custom") -export type ResultValueErrorType = T extends - | Result - | PromiseResult - | Promise> - | ((...args: any[]) => Result) - | ((...args: any[]) => PromiseResult) - | ((...args: any[]) => Promise>) +export type ResultValueErrorType = T extends (...args: any[]) => Ok | Err ? {value: V; error: E} : never + export type ResultValueType = ResultValueErrorType["value"] export type ResultErrorType = ResultValueErrorType["error"] -export type OptionValueType = T extends - | Option - | PromiseOption - | Promise> - | ((...args: any[]) => Option) - | ((...args: any[]) => PromiseOption) - | ((...args: any[]) => Promise>) - ? V +export type AsyncResultValueErrorType = T extends ( + ...args: any[] +) => Promise | Err> + ? {value: V; error: E} : never + +export type AsyncResultValueType = AsyncResultValueErrorType["value"] +export type AsyncResultErrorType = AsyncResultValueErrorType["error"] From 35708fb4e64d669c70b24150668684e6d6416f02 Mon Sep 17 00:00:00 2001 From: bkiac Date: Fri, 3 Nov 2023 22:27:37 +0100 Subject: [PATCH 5/7] Add option variants --- src/option/interface.ts | 15 ++++++++++++++- src/option/none.ts | 4 ++-- src/option/some.ts | 4 ++-- 3 files changed, 18 insertions(+), 5 deletions(-) diff --git a/src/option/interface.ts b/src/option/interface.ts index f25ddf5..b23dceb 100644 --- a/src/option/interface.ts +++ b/src/option/interface.ts @@ -31,4 +31,17 @@ export interface OptionMethods { toJSON(): {meta: "Some"; data: T} | {meta: "None"} } -export type Option = Some | None +export type SomeVariant = { + readonly some: true + readonly none: false + readonly value: T +} + +export type NoneVariant = { + readonly some: false + readonly none: true +} + +export type OptionVariants = SomeVariant | NoneVariant + +export type Option = OptionVariants & OptionMethods diff --git a/src/option/none.ts b/src/option/none.ts index 6a4df12..7a8ae76 100644 --- a/src/option/none.ts +++ b/src/option/none.ts @@ -1,9 +1,9 @@ import {Panic, UnwrapPanic} from "../error/panic" import {inspectSymbol} from "../util" -import type {OptionMethods, Option} from "./interface" +import type {OptionMethods, Option, NoneVariant} from "./interface" import type {Some} from "./some" -export class NoneImpl implements OptionMethods { +export class NoneImpl implements NoneVariant, OptionMethods { readonly some = false readonly none = true diff --git a/src/option/some.ts b/src/option/some.ts index 35da0c3..f7a9546 100644 --- a/src/option/some.ts +++ b/src/option/some.ts @@ -1,9 +1,9 @@ import type {Panic} from "../error/panic" import {inspectSymbol} from "../util" -import type {OptionMethods, Option} from "./interface" +import type {OptionMethods, Option, SomeVariant} from "./interface" import {None} from "./none" -export class SomeImpl implements OptionMethods { +export class SomeImpl implements SomeVariant, OptionMethods { readonly some = true readonly none = false readonly value: T From e080c4236a1fc8eaae486d34de7b983f7028e2e0 Mon Sep 17 00:00:00 2001 From: bkiac Date: Fri, 3 Nov 2023 22:35:01 +0100 Subject: [PATCH 6/7] Replace type with interface --- src/option/interface.ts | 4 ++-- src/result/interface.ts | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/option/interface.ts b/src/option/interface.ts index b23dceb..15cd22a 100644 --- a/src/option/interface.ts +++ b/src/option/interface.ts @@ -31,13 +31,13 @@ export interface OptionMethods { toJSON(): {meta: "Some"; data: T} | {meta: "None"} } -export type SomeVariant = { +export interface SomeVariant { readonly some: true readonly none: false readonly value: T } -export type NoneVariant = { +export interface NoneVariant { readonly some: false readonly none: true } diff --git a/src/result/interface.ts b/src/result/interface.ts index 9532983..4d36666 100644 --- a/src/result/interface.ts +++ b/src/result/interface.ts @@ -34,13 +34,13 @@ export interface ResultMethods { toJSON(): {meta: "Ok"; data: T} | {meta: "Err"; data: E} } -export type OkVariant = { +export interface OkVariant { readonly ok: true readonly err: false readonly value: T } -export type ErrVariant = { +export interface ErrVariant { readonly ok: false readonly err: true readonly error: E From b30c333b8b6612548de43cdcf05240d7c9d17b7e Mon Sep 17 00:00:00 2001 From: bkiac Date: Fri, 3 Nov 2023 22:49:34 +0100 Subject: [PATCH 7/7] Fix test type --- src/option/promise.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/option/promise.test.ts b/src/option/promise.test.ts index 8574c1a..b14ab35 100644 --- a/src/option/promise.test.ts +++ b/src/option/promise.test.ts @@ -2,7 +2,7 @@ import {describe, it, expect, vi} from "vitest" import {Panic, UnwrapPanic, PromiseOption, Some, None} from ".." function promiseSome(value: T) { - return new PromiseOption(Promise.resolve(Some(value))) + return new PromiseOption(Promise.resolve(Some(value))) } function promiseNone() {