Last active
August 8, 2019 06:25
-
-
Save Schniz/299f17cfad933a7b91f97f6c1009b29c to your computer and use it in GitHub Desktop.
A record combinator for fp-ts TaskEither
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
import * as te from 'fp-ts/lib/TaskEither'; | |
import * as arr from 'fp-ts/lib/Array'; | |
import { pipe } from 'fp-ts/lib/pipeable'; | |
type TaskEither<A, B> = te.TaskEither<A, B>; | |
type TERight<T> = T extends TaskEither<any, infer R> ? R : never; | |
/** | |
* Transforms an object of `TaskEither`s into a TaskEither of the resolved objects. | |
* Keeping keys and values type safe | |
*/ | |
export function record<L, T extends { [key: string]: TaskEither<L, any> }>( | |
rec: T, | |
): TaskEither<L, { [key in keyof T]: TERight<(typeof rec)[key]> }> { | |
return pipe( | |
Object.entries(rec), | |
arr.map(([key, value]) => | |
pipe( | |
value, | |
te.map<any, [keyof T, any]>(x => [key, x]), | |
), | |
), | |
arr.array.sequence(te.taskEither), | |
te.map(xs => { | |
const x: { [key in keyof T]: TERight<(typeof rec)[key]> } = {} as any; | |
for (const [key, val] of xs) { | |
x[key] = val; | |
} | |
return x; | |
}), | |
); | |
} |
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
// fetchJSON<T>(url): TaskEither<Error, T> | |
function fetchUserWithPosts( | |
userId: string | |
): te.TaskEither<Error, { user: User, posts: Post[] }> { | |
return record({ | |
user: fetchJSON<User>("/users/1"), | |
posts: fetchJSON<Post[]>("/users/1/posts") | |
}); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment