diff --git a/docs/docs/option.md b/docs/docs/option.md index e256b21..95b372b 100644 --- a/docs/docs/option.md +++ b/docs/docs/option.md @@ -173,6 +173,22 @@ if (option.isSome()) { } ``` +### .getOrThrow() + +```ts +Option.getOrThrow(): A | never +``` + +Returns the value contained in `Some(value)`, otherwise will throw an error. + +```ts title="Examples" +const value = Option.Some(1).getOrThrow(); +// 2 + +const value = Option.None().getOrThrow(); +// Uncaught: Tried to unwrap a Option.None value +``` + ### .isSome() ```ts diff --git a/docs/docs/result.md b/docs/docs/result.md index d4155f7..a850f67 100644 --- a/docs/docs/result.md +++ b/docs/docs/result.md @@ -168,6 +168,22 @@ Result.Error(2).getOr(1); // 1 ``` +### .getOrThrow() + +```ts +Result.getOrThrow(): A | never +``` + +If the result is `Ok(value)` returns `value`, otherwise will throw an error. + +```ts title="Examples" +const value = Result.Ok(1).getOrThrow(); +// 2 + +const value = Result.Error(2).getOrThrow(); +// Uncaught: Tried to unwrap a Result.Error value +``` + ### .mapOr(defaultValue, mapper) ```ts diff --git a/src/AsyncData.ts b/src/AsyncData.ts index 13de03b..f73d4e3 100644 --- a/src/AsyncData.ts +++ b/src/AsyncData.ts @@ -257,6 +257,16 @@ class __AsyncData { return (this as Done).value; } + /** + * Return the loaded value if present, otherwise throw an error + */ + getOrThrow(this: AsyncData): A | never { + if (this === NOT_ASKED || this === LOADING) { + throw new Error("Tried to unwrap an incomplete AsyncData"); + } + return (this as Done).value; + } + /** * Maps the value if present, returns the fallback otherwise * diff --git a/src/OptionResult.ts b/src/OptionResult.ts index 40101ae..c756e37 100644 --- a/src/OptionResult.ts +++ b/src/OptionResult.ts @@ -210,6 +210,17 @@ class __Option { return (this as Some).value; } + /** + * Return the value if present, otherwise throw an error + */ + getOrThrow(this: Option): A | never { + if (this === NONE) { + throw new Error("Tried to unwrap a Option.None value"); + } + + return (this as Some).value; + } + /** * Return the value if present, and the fallback otherwise * @@ -589,6 +600,21 @@ class __Result { return this.tag === "Ok" ? this.value : defaultValue; } + /** + * Return the value if present, otherwise throw an error + */ + getOrThrow(this: Result): A | never { + if (this.tag === "Error") { + if (typeof this.error === "string") { + throw new Error(this.error); + } + + throw new Error("Tried to unwrap a Result.Error value"); + } + + return this.value; + } + /** * Maps the value if present, returns the fallback otherwise * diff --git a/test/AsyncData.test.ts b/test/AsyncData.test.ts index b625fc6..31b0719 100644 --- a/test/AsyncData.test.ts +++ b/test/AsyncData.test.ts @@ -57,6 +57,16 @@ test("AsyncData.getOr", () => { expect(AsyncData.Done(5).getOr(0)).toEqual(5); }); +test("AsyncData.getOrThrow", () => { + expect(AsyncData.Done(5).getOrThrow()).toEqual(5); + expect(() => AsyncData.Loading().getOrThrow()).toThrowError( + "Tried to unwrap an incomplete AsyncData", + ); + expect(() => AsyncData.NotAsked().getOrThrow()).toThrowError( + "Tried to unwrap an incomplete AsyncData", + ); +}); + test("AsyncData.mapOk", () => { expect(AsyncData.NotAsked().mapOr(0, (x) => x * 2)).toEqual(0); expect(AsyncData.Loading().mapOr(0, (x) => x * 2)).toEqual(0); diff --git a/test/Option.test.ts b/test/Option.test.ts index d069d69..9981a15 100644 --- a/test/Option.test.ts +++ b/test/Option.test.ts @@ -42,6 +42,13 @@ test("Option.getOr", () => { expect(Option.None().getOr(0)).toEqual(0); }); +test("Option.getOrThrow", () => { + expect(Option.Some(1).getOrThrow()).toEqual(1); + expect(() => Option.None().getOrThrow()).toThrowError( + "Tried to unwrap a Option.None value", + ); +}); + test("Option.mapOr", () => { expect(Option.Some(1).mapOr(0, (x) => x * 2)).toEqual(2); expect(Option.None().mapOr(0, (x) => x * 2)).toEqual(0); diff --git a/test/Result.test.ts b/test/Result.test.ts index 00936a1..216eb11 100644 --- a/test/Result.test.ts +++ b/test/Result.test.ts @@ -71,6 +71,16 @@ test("Result.getOr", () => { expect(Result.Error(1).getOr(0)).toEqual(0); }); +test("Result.getOrThrow", () => { + expect(Result.Ok(1).getOrThrow()).toEqual(1); + expect(() => Result.Error(1).getOrThrow()).toThrowError( + "Tried to unwrap a Result.Error value", + ); + expect(() => Result.Error("AnErrorMessage").getOrThrow()).toThrowError( + "AnErrorMessage", + ); +}); + test("Result.mapOr", () => { expect(Result.Ok(1).mapOr(0, (x) => x * 2)).toEqual(2); expect(Result.Error(1).mapOr(0, (x) => x * 2)).toEqual(0);