Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement asyncPipe #643

Merged
merged 10 commits into from
Oct 25, 2018
34 changes: 34 additions & 0 deletions src/Helpers/async-pipe.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { identity } from 'ramda'
import { describe } from 'riteway'
import { asyncPipe } from './async-pipe'
import { toPromise } from './to-promise'

const double = (x: number) => x * 2
const inc = (x: number) => x + 1

const doubleP = toPromise(double)
const incP = toPromise(inc)

describe('asyncPipe', async (assert: any) => {
const should = 'apply the value to the functions composition correctly'

{
const value = 10
assert({
given: 'sync and async functions',
should,
actual: await asyncPipe(doubleP, inc)(value).catch(identity),
expected: inc(await doubleP(value)),
})
}

{
const value = 10
assert({
given: 'nested compositions of sync and async functions',
should,
actual: await asyncPipe(doubleP, inc, asyncPipe(double, incP))(value).catch(identity),
expected: await incP(double(inc(await doubleP(value)))),
})
}
})
4 changes: 4 additions & 0 deletions src/Helpers/async-pipe.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
type Func = (v?: any) => any | Promise<any>
Copy link
Member

@lautarodragan lautarodragan Oct 25, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sadly TypeScript doesn't have any decent support for the the most important FP functions like curry, compose, pipe... and even some cases of reduce. See this comment by one of the authors of Ramda's type declarations, and the Variadict Kinds Proposal.

You can hack around TS' limitation by providing one function overload per function arity.

It isn't pretty or very maintainable, but I think it still would add a lot of value since we rarely compose/pipe too many functions and it'd give us type safety in our pipes.

Wanna give it a shot?

Feel free to merge as-is though, code looks good and the tests are awesome.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, for some reason I though they had solved it partial in TS 3.0, but when I started looking around it seems they have not.

I think I will merge this as is, then I will go back and add the better typings.


type asyncPipe = (...fns: Func[]) => (v?: any) => Promise<any>
export const asyncPipe: asyncPipe = (...fns) => v => fns.reduce(async (a, c) => c(await a), v)
1 change: 1 addition & 0 deletions tests/unit/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import '../../src/Helpers/Configuration.test'
import '../../src/Helpers/FetchError.test.ts'
import '../../src/Helpers/Logging.test.ts'
import '../../src/Helpers/Time.test.ts'
import '../../src/Helpers/async-pipe.test.ts'
import '../../src/Helpers/camelCaseToScreamingSnakeCase.test'
import '../../src/Helpers/isTruthy.test'
import '../../src/Helpers/to-promise.test.ts'
Expand Down