Skip to content

Commit 1ff3446

Browse files
committed
add: isNotError, whenNotError, whenNotErrorAll, and related types
1 parent c657633 commit 1ff3446

File tree

7 files changed

+153
-0
lines changed

7 files changed

+153
-0
lines changed

src/types/types.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
11
/* eslint-disable @typescript-eslint/explicit-function-return-type */
22

33
export type UndefinedOr<R> = undefined | R
4+
export type ErrorOr<T> = Error | T
5+
export type NotError<T> = Exclude<T, Error>

src/utils/isNotError.test.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import test from 'ava'
2+
import { isNotError } from './isNotError'
3+
4+
test('Returns false when the passed value is Error', (t) => {
5+
t.false(isNotError(new Error()))
6+
})
7+
8+
test('Returns true when the passed value is not Error', (t) => {
9+
t.true(isNotError(undefined))
10+
})

src/utils/isNotError.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
import { NotError } from '../types/types'
2+
3+
export const isNotError = <T>(t: T): t is NotError<T> =>
4+
t instanceof Error ? false : true

src/utils/whenNotError.test.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import test from 'ava'
2+
import { whenNotError } from './whenNotError'
3+
4+
test(`Executes the passed function when the passed value is not Error.`, (t) => {
5+
const result = whenNotError(null, (v) => {
6+
t.is(v, null)
7+
return 'done'
8+
})
9+
t.is(result, 'done')
10+
})
11+
12+
test(`Returns Error when the passed value is Error.`, (t) => {
13+
const err = new Error('ERROR')
14+
const result = whenNotError(err, () => true)
15+
t.is(result, err)
16+
t.is((result as Error).message, 'ERROR')
17+
})

src/utils/whenNotError.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import { cond, always, T } from 'ramda'
2+
import { ErrorOr, NotError } from '../types/types'
3+
import { isNotError } from './isNotError'
4+
5+
export const whenNotError = <D, F>(
6+
depends: D,
7+
fn: (d: NotError<D>) => F
8+
): ErrorOr<F> =>
9+
cond([
10+
[isNotError, fn],
11+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
12+
[T, always(depends as any)],
13+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
14+
])(depends as any)

src/utils/whenNotErrorAll.test.ts

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import test from 'ava'
2+
import { whenNotErrorAll } from './whenNotErrorAll'
3+
4+
test(`Executes the passed function when the passed array's values are not Error all.`, (t) => {
5+
const result = whenNotErrorAll(
6+
['', 0, [], false, 'false', '0'],
7+
([empty, zero, arr, f, strF, str0]) => {
8+
t.is(empty, '')
9+
t.is(zero, 0)
10+
t.deepEqual(arr, [])
11+
t.is(f, false)
12+
t.is(strF, 'false')
13+
t.is(str0, '0')
14+
return 'done'
15+
}
16+
)
17+
t.is(result, 'done')
18+
})
19+
20+
test(`Returns Error when the passed array's includes Error.`, (t) => {
21+
const err = new Error('ERROR')
22+
const result = whenNotErrorAll(['', 0, [], false, err], () => true)
23+
t.is(result, err)
24+
t.is((result as Error).message, 'ERROR')
25+
})
26+
27+
test(`Returns the first Error if the passed array includes multiple errors.`, (t) => {
28+
const err1 = new Error('ERROR1')
29+
const err2 = new Error('ERROR2')
30+
const err3 = new Error('ERROR3')
31+
const result = whenNotErrorAll(
32+
['', err1, [], err2, undefined, err3],
33+
() => true
34+
)
35+
t.is(result, err1)
36+
t.is((result as Error).message, 'ERROR1')
37+
})

src/utils/whenNotErrorAll.ts

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
import { T, always, cond } from 'ramda'
2+
import { whenDefined } from './whenDefined'
3+
import { isNotError } from './isNotError'
4+
import { ErrorOr, NotError } from '../types/types'
5+
6+
const passAll = <D>(depends: D): boolean =>
7+
depends instanceof Array ? depends.every(isNotError) : isNotError(depends)
8+
9+
export function whenNotErrorAll<D1, F>(
10+
depends: readonly [D1],
11+
fn: (d: readonly [NotError<D1>]) => F
12+
): ErrorOr<F>
13+
export function whenNotErrorAll<D1, D2, F>(
14+
depends: readonly [D1, D2],
15+
fn: (d: readonly [NotError<D1>, NotError<D2>]) => F
16+
): ErrorOr<F>
17+
export function whenNotErrorAll<D1, D2, D3, F>(
18+
depends: readonly [D1, D2, D3],
19+
fn: (d: readonly [NotError<D1>, NotError<D2>, NotError<D3>]) => F
20+
): ErrorOr<F>
21+
export function whenNotErrorAll<D1, D2, D3, D4, F>(
22+
depends: readonly [D1, D2, D3, D4],
23+
fn: (
24+
d: readonly [NotError<D1>, NotError<D2>, NotError<D3>, NotError<D4>]
25+
) => F
26+
): ErrorOr<F>
27+
export function whenNotErrorAll<D1, D2, D3, D4, D5, F>(
28+
depends: readonly [D1, D2, D3, D4, D5],
29+
fn: (
30+
d: readonly [
31+
NotError<D1>,
32+
NotError<D2>,
33+
NotError<D3>,
34+
NotError<D4>,
35+
NotError<D5>
36+
]
37+
) => F
38+
): ErrorOr<F>
39+
export function whenNotErrorAll<D1, D2, D3, D4, D5, D6, F>(
40+
depends: readonly [D1, D2, D3, D4, D5, D6],
41+
fn: (
42+
d: readonly [
43+
NotError<D1>,
44+
NotError<D2>,
45+
NotError<D3>,
46+
NotError<D4>,
47+
NotError<D5>,
48+
NotError<D6>
49+
]
50+
) => F
51+
): ErrorOr<F>
52+
53+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
54+
export function whenNotErrorAll(depends: unknown, fn: any): unknown {
55+
return whenDefined(
56+
depends,
57+
cond([
58+
[passAll, (deps) => fn(deps)],
59+
[
60+
T,
61+
always(
62+
depends instanceof Array
63+
? depends.find((d) => !isNotError(d))
64+
: depends
65+
),
66+
],
67+
])
68+
)
69+
}

0 commit comments

Comments
 (0)