Skip to content

Commit

Permalink
✨ Improve pipe function of type definition
Browse files Browse the repository at this point in the history
Closes #77
  • Loading branch information
TomokiMiyauci committed Jun 3, 2021
1 parent cef97ed commit 9c83312
Show file tree
Hide file tree
Showing 2 changed files with 301 additions and 7 deletions.
280 changes: 275 additions & 5 deletions src/pipe.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { AnyFn } from './types/index.ts'
* Performs left-to-right function composition.
*
* @param functions - Multi any functions
* @returns - A `function` what argument is `function[0]` argument
* @returns A `function` what argument is `function[0]` argument
*
* @remarks
* The first argument may have any arity; the remaining arguments must be unary.
Expand All @@ -17,9 +17,279 @@ import { AnyFn } from './types/index.ts'
*
* @beta
*/
const pipe =
<T extends [AnyFn, AnyFn]>(...functions: T) =>
(...val: Parameters<T[0]>): ReturnType<T[1]> =>
functions[1](functions[0](...val)) as any
const pipe: Pipe =
(...args: AnyFn[]) =>
(initialArg: unknown) =>
args.reduce((acc, cur) => cur(acc), initialArg)

export { pipe }

type Arity1Fn<T = any, U = unknown> = (args: T) => U

type Pipe = {
<F1 extends AnyFn>(fn1: F1): (...initialArg: Parameters<F1>) => ReturnType<F1>

<F1 extends AnyFn, F2 extends Arity1Fn<ReturnType<F1>>>(...fn1: [F1, F2]): (
...initialArg: Parameters<F1>
) => ReturnType<F2>

<
F1 extends AnyFn,
F2 extends Arity1Fn<ReturnType<F1>>,
F3 extends Arity1Fn<ReturnType<F2>>
>(
...fn1: [F1, F2, F3]
): (...initialArg: Parameters<F1>) => ReturnType<F3>

<
F1 extends AnyFn,
F2 extends Arity1Fn<ReturnType<F1>>,
F3 extends Arity1Fn<ReturnType<F2>>,
F4 extends Arity1Fn<ReturnType<F3>>
>(
...fn1: [F1, F2, F3, F4]
): (...initialArg: Parameters<F1>) => ReturnType<F4>

<
F1 extends AnyFn,
F2 extends Arity1Fn<ReturnType<F1>>,
F3 extends Arity1Fn<ReturnType<F2>>,
F4 extends Arity1Fn<ReturnType<F3>>,
F5 extends Arity1Fn<ReturnType<F4>>
>(
...fn1: [F1, F2, F3, F4, F5]
): (...initialArg: Parameters<F1>) => ReturnType<F5>

<
F1 extends AnyFn,
F2 extends Arity1Fn<ReturnType<F1>>,
F3 extends Arity1Fn<ReturnType<F2>>,
F4 extends Arity1Fn<ReturnType<F3>>,
F5 extends Arity1Fn<ReturnType<F4>>,
F6 extends Arity1Fn<ReturnType<F5>>
>(
...fn1: [F1, F2, F3, F4, F5, F6]
): (...initialArg: Parameters<F1>) => ReturnType<F6>

<
F1 extends AnyFn,
F2 extends Arity1Fn<ReturnType<F1>>,
F3 extends Arity1Fn<ReturnType<F2>>,
F4 extends Arity1Fn<ReturnType<F3>>,
F5 extends Arity1Fn<ReturnType<F4>>,
F6 extends Arity1Fn<ReturnType<F5>>,
F7 extends Arity1Fn<ReturnType<F6>>
>(
...fn1: [F1, F2, F3, F4, F5, F6, F7]
): (...initialArg: Parameters<F1>) => ReturnType<F7>

<
F1 extends AnyFn,
F2 extends Arity1Fn<ReturnType<F1>>,
F3 extends Arity1Fn<ReturnType<F2>>,
F4 extends Arity1Fn<ReturnType<F3>>,
F5 extends Arity1Fn<ReturnType<F4>>,
F6 extends Arity1Fn<ReturnType<F5>>,
F7 extends Arity1Fn<ReturnType<F6>>,
F8 extends Arity1Fn<ReturnType<F7>>
>(
...fn1: [F1, F2, F3, F4, F5, F6, F7, F8]
): (...initialArg: Parameters<F1>) => ReturnType<F8>

<
F1 extends AnyFn,
F2 extends Arity1Fn<ReturnType<F1>>,
F3 extends Arity1Fn<ReturnType<F2>>,
F4 extends Arity1Fn<ReturnType<F3>>,
F5 extends Arity1Fn<ReturnType<F4>>,
F6 extends Arity1Fn<ReturnType<F5>>,
F7 extends Arity1Fn<ReturnType<F6>>,
F8 extends Arity1Fn<ReturnType<F7>>,
F9 extends Arity1Fn<ReturnType<F8>>
>(
...fn1: [F1, F2, F3, F4, F5, F6, F7, F8, F9]
): (...initialArg: Parameters<F1>) => ReturnType<F9>

<
F1 extends AnyFn,
F2 extends Arity1Fn<ReturnType<F1>>,
F3 extends Arity1Fn<ReturnType<F2>>,
F4 extends Arity1Fn<ReturnType<F3>>,
F5 extends Arity1Fn<ReturnType<F4>>,
F6 extends Arity1Fn<ReturnType<F5>>,
F7 extends Arity1Fn<ReturnType<F6>>,
F8 extends Arity1Fn<ReturnType<F7>>,
F9 extends Arity1Fn<ReturnType<F8>>,
F10 extends Arity1Fn<ReturnType<F9>>
>(
...fn1: [F1, F2, F3, F4, F5, F6, F7, F8, F9, F10]
): (...initialArg: Parameters<F1>) => ReturnType<F10>

<
F1 extends AnyFn,
F2 extends Arity1Fn<ReturnType<F1>>,
F3 extends Arity1Fn<ReturnType<F2>>,
F4 extends Arity1Fn<ReturnType<F3>>,
F5 extends Arity1Fn<ReturnType<F4>>,
F6 extends Arity1Fn<ReturnType<F5>>,
F7 extends Arity1Fn<ReturnType<F6>>,
F8 extends Arity1Fn<ReturnType<F7>>,
F9 extends Arity1Fn<ReturnType<F8>>,
F10 extends Arity1Fn<ReturnType<F9>>,
F11 extends Arity1Fn<ReturnType<F10>>
>(
...fn1: [F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11]
): (...initialArg: Parameters<F1>) => ReturnType<F11>

<
F1 extends AnyFn,
F2 extends Arity1Fn<ReturnType<F1>>,
F3 extends Arity1Fn<ReturnType<F2>>,
F4 extends Arity1Fn<ReturnType<F3>>,
F5 extends Arity1Fn<ReturnType<F4>>,
F6 extends Arity1Fn<ReturnType<F5>>,
F7 extends Arity1Fn<ReturnType<F6>>,
F8 extends Arity1Fn<ReturnType<F7>>,
F9 extends Arity1Fn<ReturnType<F8>>,
F10 extends Arity1Fn<ReturnType<F9>>,
F11 extends Arity1Fn<ReturnType<F10>>,
F12 extends Arity1Fn<ReturnType<F11>>
>(
...fn1: [F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12]
): (...initialArg: Parameters<F1>) => ReturnType<F12>

<
F1 extends AnyFn,
F2 extends Arity1Fn<ReturnType<F1>>,
F3 extends Arity1Fn<ReturnType<F2>>,
F4 extends Arity1Fn<ReturnType<F3>>,
F5 extends Arity1Fn<ReturnType<F4>>,
F6 extends Arity1Fn<ReturnType<F5>>,
F7 extends Arity1Fn<ReturnType<F6>>,
F8 extends Arity1Fn<ReturnType<F7>>,
F9 extends Arity1Fn<ReturnType<F8>>,
F10 extends Arity1Fn<ReturnType<F9>>,
F11 extends Arity1Fn<ReturnType<F10>>,
F12 extends Arity1Fn<ReturnType<F11>>,
F13 extends Arity1Fn<ReturnType<F12>>
>(
...fn1: [F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, F13]
): (...initialArg: Parameters<F1>) => ReturnType<F13>

<
F1 extends AnyFn,
F2 extends Arity1Fn<ReturnType<F1>>,
F3 extends Arity1Fn<ReturnType<F2>>,
F4 extends Arity1Fn<ReturnType<F3>>,
F5 extends Arity1Fn<ReturnType<F4>>,
F6 extends Arity1Fn<ReturnType<F5>>,
F7 extends Arity1Fn<ReturnType<F6>>,
F8 extends Arity1Fn<ReturnType<F7>>,
F9 extends Arity1Fn<ReturnType<F8>>,
F10 extends Arity1Fn<ReturnType<F9>>,
F11 extends Arity1Fn<ReturnType<F10>>,
F12 extends Arity1Fn<ReturnType<F11>>,
F13 extends Arity1Fn<ReturnType<F12>>,
F14 extends Arity1Fn<ReturnType<F13>>
>(
...fn1: [F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, F13, F14]
): (...initialArg: Parameters<F1>) => ReturnType<F14>

<
F1 extends AnyFn,
F2 extends Arity1Fn<ReturnType<F1>>,
F3 extends Arity1Fn<ReturnType<F2>>,
F4 extends Arity1Fn<ReturnType<F3>>,
F5 extends Arity1Fn<ReturnType<F4>>,
F6 extends Arity1Fn<ReturnType<F5>>,
F7 extends Arity1Fn<ReturnType<F6>>,
F8 extends Arity1Fn<ReturnType<F7>>,
F9 extends Arity1Fn<ReturnType<F8>>,
F10 extends Arity1Fn<ReturnType<F9>>,
F11 extends Arity1Fn<ReturnType<F10>>,
F12 extends Arity1Fn<ReturnType<F11>>,
F13 extends Arity1Fn<ReturnType<F12>>,
F14 extends Arity1Fn<ReturnType<F13>>,
F15 extends Arity1Fn<ReturnType<F14>>
>(
...fn1: [F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, F13, F14, F15]
): (...initialArg: Parameters<F1>) => ReturnType<F15>

<
F1 extends AnyFn,
F2 extends Arity1Fn<ReturnType<F1>>,
F3 extends Arity1Fn<ReturnType<F2>>,
F4 extends Arity1Fn<ReturnType<F3>>,
F5 extends Arity1Fn<ReturnType<F4>>,
F6 extends Arity1Fn<ReturnType<F5>>,
F7 extends Arity1Fn<ReturnType<F6>>,
F8 extends Arity1Fn<ReturnType<F7>>,
F9 extends Arity1Fn<ReturnType<F8>>,
F10 extends Arity1Fn<ReturnType<F9>>,
F11 extends Arity1Fn<ReturnType<F10>>,
F12 extends Arity1Fn<ReturnType<F11>>,
F13 extends Arity1Fn<ReturnType<F12>>,
F14 extends Arity1Fn<ReturnType<F13>>,
F15 extends Arity1Fn<ReturnType<F14>>,
F16 extends Arity1Fn<ReturnType<F15>>
>(
...fn1: [
F1,
F2,
F3,
F4,
F5,
F6,
F7,
F8,
F9,
F10,
F11,
F12,
F13,
F14,
F15,
F16
]
): (...initialArg: Parameters<F1>) => ReturnType<F16>

<
F1 extends AnyFn,
F2 extends Arity1Fn<ReturnType<F1>>,
F3 extends Arity1Fn<ReturnType<F2>>,
F4 extends Arity1Fn<ReturnType<F3>>,
F5 extends Arity1Fn<ReturnType<F4>>,
F6 extends Arity1Fn<ReturnType<F5>>,
F7 extends Arity1Fn<ReturnType<F6>>,
F8 extends Arity1Fn<ReturnType<F7>>,
F9 extends Arity1Fn<ReturnType<F8>>,
F10 extends Arity1Fn<ReturnType<F9>>,
F11 extends Arity1Fn<ReturnType<F10>>,
F12 extends Arity1Fn<ReturnType<F11>>,
F13 extends Arity1Fn<ReturnType<F12>>,
F14 extends Arity1Fn<ReturnType<F13>>,
F15 extends Arity1Fn<ReturnType<F14>>,
F16 extends Arity1Fn<ReturnType<F15>>,
F17 extends Arity1Fn<ReturnType<F16>>
>(
...fn1: [
F1,
F2,
F3,
F4,
F5,
F6,
F7,
F8,
F9,
F10,
F11,
F12,
F13,
F14,
F15,
F16,
F17
]
): (...initialArg: Parameters<F1>) => ReturnType<F17>
}
28 changes: 26 additions & 2 deletions test/pipe.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,15 @@ import { AnyFn } from '../src/types/index.ts'
import { assertEqual } from './asserts.ts'

Deno.test('pipe', () => {
const table: [[AnyFn, AnyFn], unknown, unknown][] = [
const table: [AnyFn[], unknown, unknown][] = [
[[() => {}, () => {}], '', undefined],
[[() => {}, () => true], '', true],
[[() => {}, () => true], 1, true],
[[() => 1, (n: number) => n + 1], 1, 2],
[[isNumber, N], '', true],
[[N, N], 1, true],
[[isNumber, N], 1, false]
[[isNumber, N], 1, false],
[[() => true, () => false, () => true, () => false], 1, false]
]

table.forEach(([[fn1, fn2], argument, expected]) => {
Expand All @@ -27,4 +28,27 @@ Deno.test('pipe', () => {
})

assertEqual<boolean>(pipe(isNumber, N)(1))

const pipetest = pipe(
(_: number, __: string, ___: number) => {
return 1 as const
},
(a) => a,
() => [] as [],
(a) => a,
(a) => a,
(a) => a,
(_) => '' as const,
(a) => a,
(a) => a,
(a) => a,
(a) => a,
(a) => a,
(_) => 1 as const,
(a) => a,
(a) => a,
(_) => '' as const,
(a) => a
)
assertEqual<''>(pipetest(1, '', 1))
})

0 comments on commit 9c83312

Please sign in to comment.