-
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
✨ Add ifElseFn and change ifElse function
- Loading branch information
1 parent
9754460
commit a13525b
Showing
6 changed files
with
143 additions
and
67 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
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 |
---|---|---|
@@ -1,40 +1,36 @@ | ||
// Copyright 2021-present the Fonction authors. All rights reserved. MIT license. | ||
import { isFunction } from './isFunction.ts' | ||
|
||
import { NN } from './NN.ts' | ||
import { Falsy } from './types/index.ts' | ||
/** | ||
* Creates a function that will process either the `onTrue` or the `onFalse` function depending upon the result of the condition predicate. | ||
* Return the `onTrue` or the `onFalse` value depending upon the result of the condition `val`. | ||
* | ||
* @param condition - A predicate function | ||
* @param onTrue - Any value or A function to invoke when the `condition` evaluates to a truthy value | ||
* @param onFalse - Any value or A function to invoke when the `condition` evaluates to a falsy value | ||
* @returns A new function that will process either the `onTrue` or the `onFalse` function depending upon the result of the `condition` predicate | ||
* @param val - A predicate value | ||
* @param onTrue - The `val` evaluates to a truthy value | ||
* @param onFalse - The `val` evaluates to a falsy value | ||
* @returns The result of `!!val` ? `onTrue` : `onFalse` | ||
* | ||
* @example | ||
* ```ts | ||
* ifElse((x: number) => x > 10, 'big', 'small')(20) // 'big' | ||
* const fn = ifElse((x: number) => x > 10, (x) => x + 1, (x) => x - 1) | ||
* fn(11) // 12 | ||
* fn(9) // 8 | ||
* ifElse(true, 1, 0) // 1 | ||
* ifElse(false, 1, 0) // 0 | ||
* ifElse(undefined, 1, 0) // 0 | ||
* ``` | ||
* | ||
* @category `Logic` | ||
* | ||
* @see Related to {@link ifElseFn} | ||
* | ||
* @beta | ||
*/ | ||
const ifElse = <V, R extends boolean, T, F>( | ||
condition: (val: V) => R, | ||
onTrue: T | ((val: V) => T), | ||
onFalse: F | ((val: V) => F) | ||
) => (val: V): R extends true ? T : R extends false ? F : T | F => { | ||
if (condition(val)) { | ||
return isFunction(onTrue) | ||
? (onTrue as (val: V) => T)(val) | ||
: ((onTrue as T) as any) | ||
} else { | ||
return isFunction(onFalse) | ||
? (onFalse as (val: V) => F)(val) | ||
: ((onFalse as F) as any) | ||
} | ||
} | ||
const ifElse = <V, T, F>( | ||
val: V, | ||
onTrue: T, | ||
onFalse: F | ||
): V extends Falsy ? F : V extends true ? T : T | F => | ||
(NN(val) ? onTrue : onFalse) as V extends Falsy | ||
? F | ||
: V extends true | ||
? T | ||
: T | F | ||
|
||
export { ifElse } |
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,42 @@ | ||
// Copyright 2021-present the Fonction authors. All rights reserved. MIT license. | ||
import { isFunction } from './isFunction.ts' | ||
import { Falsy } from './types/index.ts' | ||
/** | ||
* Creates a function that will process either the `onTrue` or the `onFalse` function depending upon the result of the condition predicate. | ||
* | ||
* @param condition - A predicate function | ||
* @param onTrue - Any value or A function to invoke when the `condition` evaluates to a truthy value | ||
* @param onFalse - Any value or A function to invoke when the `condition` evaluates to a falsy value | ||
* @returns A new function that will process either the `onTrue` or the `onFalse` function depending upon the result of the `condition` predicate | ||
* | ||
* @example | ||
* ```ts | ||
* ifElseFn((x: number) => x > 10, 'big', 'small')(20) // 'big' | ||
* const fn = ifElseFn((x: number) => x > 10, (x) => x + 1, (x) => x - 1) | ||
* fn(11) // 12 | ||
* fn(9) // 8 | ||
* ``` | ||
* | ||
* @category `Logic` | ||
* | ||
* @see Related to {@link ifElse} | ||
* | ||
* @beta | ||
*/ | ||
const ifElseFn = <V, R, T, F>( | ||
condition: (val: V) => R, | ||
onTrue: T | ((val: V) => T), | ||
onFalse: F | ((val: V) => F) | ||
) => (val: V): R extends true ? T : R extends Falsy ? F : T | F => { | ||
if (condition(val)) { | ||
return isFunction(onTrue) | ||
? (onTrue as (val: V) => T)(val) | ||
: ((onTrue as T) as any) | ||
} else { | ||
return isFunction(onFalse) | ||
? (onFalse as (val: V) => F)(val) | ||
: ((onFalse as F) as any) | ||
} | ||
} | ||
|
||
export { ifElseFn } |
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,55 @@ | ||
// Copyright 2021-present the Fonction authors. All rights reserved. MIT license. | ||
import { assertEquals } from '../deps.ts' | ||
import { ifElseFn } from '../src/ifElseFn.ts' | ||
import { assertEqual } from './asserts.ts' | ||
|
||
Deno.test('ifElseFn', () => { | ||
const table: [ | ||
(val: any) => boolean, | ||
((val: unknown) => boolean) | unknown, | ||
((val: unknown) => boolean) | unknown, | ||
unknown, | ||
unknown | ||
][] = [ | ||
[() => true, 1, 0, 1, 1], | ||
[() => false, 1, 0, 1, 0], | ||
[(x: unknown) => !!x, 1, 0, 1, 1], | ||
[(x: unknown) => !!x, 1, 0, 0, 0], | ||
[(x: unknown) => !!x, () => 2, 0, 1, 2], | ||
[(x: unknown) => !!x, () => 2, () => 3, 0, 3], | ||
[(x: unknown) => !!x, (x: number) => x + 1, () => 3, 1, 2], | ||
[(x: unknown) => !!x, (x: number) => x + 1, (x: number) => x - 1, 0, -1] | ||
] | ||
|
||
table.forEach(([condition, onTrue, onFalse, val, expected]) => { | ||
assertEquals( | ||
ifElseFn(condition, onTrue, onFalse)(val), | ||
expected, | ||
`ifElseFn(${condition}, ${onTrue}, ${onFalse})(${val}) -> ${expected}` | ||
) | ||
}) | ||
|
||
assertEqual<number>(ifElseFn(() => true as const, 1, 0)(1)) | ||
assertEqual<1>(ifElseFn(() => true as const, 1 as const, 0 as const)(1)) | ||
assertEqual<0>(ifElseFn(() => false as const, 1 as const, 0 as const)(1)) | ||
assertEqual<0>(ifElseFn(() => '' as const, 1 as const, 0 as const)(1)) | ||
assertEqual<0>(ifElseFn(() => undefined, 1 as const, 0 as const)(1)) | ||
assertEqual<0>(ifElseFn(() => null, 1 as const, 0 as const)(1)) | ||
assertEqual<0>(ifElseFn(() => 0 as const, 1 as const, 0 as const)(1)) | ||
assertEqual<1 | 0>(ifElseFn(() => true as boolean, 1 as const, 0 as const)(1)) | ||
assertEqual<1 | 0>(ifElseFn((x: string) => !!x, 1 as const, 0 as const)('')) | ||
assertEqual<number>( | ||
ifElseFn( | ||
(x: number) => !!x, | ||
(x: number) => x + 1, | ||
0 as const | ||
)(0) | ||
) | ||
assertEqual<number>( | ||
ifElseFn( | ||
(x: number) => !!x, | ||
(x: number) => x + 1, | ||
(x: number) => x - 1 | ||
)(0) | ||
) | ||
}) |