-
Notifications
You must be signed in to change notification settings - Fork 30
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add isResult, isResultOk, and isResultErr functions (#172)
- Loading branch information
1 parent
8e7dfc3
commit 08d4329
Showing
10 changed files
with
230 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
--- | ||
title: isResult | ||
description: Check if a value is a Result tuple | ||
--- | ||
|
||
### Usage | ||
|
||
Check if a value is a `Result` tuple. | ||
|
||
**Don't know what that is?** Read the [Result](#result) section further down. | ||
|
||
```ts | ||
import * as _ from 'radashi' | ||
|
||
_.isResult([undefined, 42]) // => true | ||
_.isResult([new Error(), undefined]) // => true | ||
|
||
// Result tuples cannot have both a value and an error, or neither. | ||
_.isResult([undefined, undefined]) // => false | ||
_.isResult([new Error(), true]) // => false | ||
|
||
// Tuple must be of length 2. | ||
_.isResult([new Error()]) // => false | ||
_.isResult([undefined, true, undefined]) // => false | ||
|
||
// Non-tuple values are false. | ||
_.isResult([]) // => false | ||
_.isResult({}) // => false | ||
_.isResult(null) // => false | ||
``` | ||
|
||
Also see the related [isResultOk](/typed/isResultOk) and [isResultErr](/typed/isResultErr) functions. | ||
|
||
## Types In-Depth | ||
|
||
### Result | ||
|
||
“Results” are tuples of 2 elements (an **error** and a **result value**). | ||
|
||
- The first element is always the **error**, or `undefined` if the operation was successful. | ||
- The second element is always the **result value**, or `undefined` if the operation failed. | ||
- These tuples are represented by the `Result<TResult, TError>` type. | ||
- A default error type of `Error` is used when no error type is explicitly defined (e.g. `Result<string>`). | ||
- The default error type is _not_ `unknown` because we assume you're following best practices and so you avoid throwing anything but `Error` objects. | ||
- You're free to define the error type to be anything (like `Result<string, Error | number>`), not just `Error` types. | ||
|
||
### Ok and Err | ||
|
||
There are 2 types of result: `Ok<TResult>` and `Err<TError>`. | ||
|
||
- The `Ok` type represents a successful operation. It's a tuple of `[undefined, TResult]`. | ||
- The `Err` type represents a failed operation. It's a tuple of `[TError, undefined]`. | ||
|
||
The names "Ok" and "Err" are inspired by Rust's `std::result` module. | ||
|
||
To check for an `Ok` result, do this: | ||
|
||
```ts | ||
if (isResult(value) && value[0] == null) { | ||
value // <-- now an Ok<unknown> type | ||
value[1] // <-- This is the resulting value! | ||
} | ||
``` | ||
|
||
To check for an `Err` result, do this: | ||
|
||
```ts | ||
if (isResult(value) && value[0] != null) { | ||
value // <-- now an Err<Error> type | ||
value[0] // <-- This is the error! | ||
} | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
--- | ||
title: isResultErr | ||
description: Returns true for failed Result tuple | ||
--- | ||
|
||
### Usage | ||
|
||
Check if a value is both a `Result` tuple and an `Err` result. | ||
|
||
```ts | ||
declare const value: unknown | ||
|
||
if (isResultErr(value)) { | ||
value // <-- now an Err<Error> type | ||
value[0] // <-- This is the error! | ||
} | ||
``` | ||
|
||
Also see the related [isResult](/typed/isResult) and [isResultOk](/typed/isResultOk) functions. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
--- | ||
title: isResultOk | ||
description: Returns true for successful Result tuple | ||
--- | ||
|
||
### Usage | ||
|
||
Check if a value is both a `Result` tuple and an `Ok` result. | ||
|
||
```ts | ||
declare const value: unknown | ||
|
||
if (isResultOk(value)) { | ||
value // <-- now an Ok<unknown> type | ||
value[1] // <-- This is the resulting value! | ||
} | ||
``` | ||
|
||
Also see the related [isResult](/typed/isResult) and [isResultErr](/typed/isResultErr) functions. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
import { isArray, type Result } from 'radashi' | ||
|
||
/** | ||
* Returns true if the value is a `Result` tuple. | ||
* | ||
* @see https://radashi-org.github.io/reference/typed/isResult | ||
* @example | ||
* ```ts | ||
* isResult([undefined, 42]) => true | ||
* isResult([new Error(), undefined]) => true | ||
* | ||
* // Result tuples cannot have both a value and an error, or neither. | ||
* isResult([undefined, undefined]) => false | ||
* isResult([new Error(), true]) => false | ||
* | ||
* // Tuple must be of length 2. | ||
* isResult([new Error()]) => false | ||
* isResult([undefined, true, undefined]) => false | ||
* | ||
* // Non-tuple values are false. | ||
* isResult([]) => false | ||
* isResult({}) => false | ||
* isResult(null) => false | ||
* ``` | ||
*/ | ||
export function isResult(value: unknown): value is Result<unknown, unknown> { | ||
return ( | ||
isArray(value) && | ||
value.length === 2 && | ||
(value[0] === undefined) !== (value[1] === undefined) | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
import { type Err, isResult } from 'radashi' | ||
|
||
/** | ||
* Returns true if the value is an `Err` result. | ||
* | ||
* @see https://radashi-org.github.io/reference/typed/isResultErr | ||
* @example | ||
* ```ts | ||
* isResultErr([new Error(), undefined]) // true | ||
* isResultErr([undefined, "hello"]) // false | ||
* ``` | ||
*/ | ||
export function isResultErr<TError = Error>( | ||
value: unknown, | ||
): value is Err<TError> { | ||
return isResult(value) && value[0] !== undefined | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
import { isResult, type Ok } from 'radashi' | ||
|
||
/** | ||
* Returns true if the value is an `Ok` result. | ||
* | ||
* @see https://radashi-org.github.io/reference/typed/isResultOk | ||
* @example | ||
* ```ts | ||
* isResultOk([undefined, "hello"]) // true | ||
* isResultOk([new Error(), undefined]) // false | ||
* ``` | ||
*/ | ||
export function isResultOk<TValue = unknown>( | ||
value: unknown, | ||
): value is Ok<TValue> { | ||
return isResult(value) && value[0] === undefined | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
import * as _ from 'radashi' | ||
|
||
describe('isResult', () => { | ||
test('should return true for valid Result tuples', () => { | ||
expect(_.isResult([undefined, 42])).toBe(true) | ||
expect(_.isResult([new Error(), undefined])).toBe(true) | ||
}) | ||
|
||
test('should return false for invalid Result tuples', () => { | ||
expect(_.isResult([undefined, undefined])).toBe(false) | ||
expect(_.isResult([new Error(), true])).toBe(false) | ||
expect(_.isResult([new Error()])).toBe(false) | ||
expect(_.isResult([undefined, true, undefined])).toBe(false) | ||
}) | ||
|
||
test('should return false for non-tuple values', () => { | ||
expect(_.isResult([])).toBe(false) | ||
expect(_.isResult({})).toBe(false) | ||
expect(_.isResult(null)).toBe(false) | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
import * as _ from 'radashi' | ||
|
||
describe('isResultErr', () => { | ||
test('valid Err results', () => { | ||
expect(_.isResultErr([new Error(), undefined])).toBe(true) | ||
}) | ||
test('invalid Err results', () => { | ||
expect(_.isResultErr([undefined, 42])).toBe(false) | ||
}) | ||
test('other values', () => { | ||
expect(_.isResultErr([])).toBe(false) | ||
expect(_.isResultErr({})).toBe(false) | ||
expect(_.isResultErr(null)).toBe(false) | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
import * as _ from 'radashi' | ||
|
||
describe('isResultOk', () => { | ||
test('valid Ok results', () => { | ||
expect(_.isResultOk([undefined, 42])).toBe(true) | ||
}) | ||
test('invalid Ok results', () => { | ||
expect(_.isResultOk([new Error(), undefined])).toBe(false) | ||
}) | ||
test('other values', () => { | ||
expect(_.isResultOk([])).toBe(false) | ||
expect(_.isResultOk({})).toBe(false) | ||
expect(_.isResultOk(null)).toBe(false) | ||
}) | ||
}) |