Search code examples
typescriptfunctional-programmingfp-ts

Somehow end up with a Promise<Either<Errors, Job>> instead of TaskEither<Errors, Job>


I'm not really comfortable with FP-TS just yet (or functional programming in general), so I may be doing some things wrong here.

I have the following function where I'd like to return a TaskEither<Errors, Job> but I can't seem to get it to work.

This one returns Promise<Either<Errors, Job>>

export function storeJob(job: CreateJob): TaskEither<Errors, Job> {
  const dto = toCreateDto(job)
  const insertQuery = createInsertQuery('jobs')(dto)

  return pipe(
      insertQuery, // string
      query, // TaskEither<Error, unknown>
      fromEither(fromDto(dto) // Either<Errors, Job> ) // TaskEither<Errors, Job> 
  ) // Promise<Either<Errors, Job>>
}

Another try (only changed the last pipe, added map) I did returns TaskEither<Error, TaskEither<Errors, Job>>

export function storeJob(job: CreateJob): TaskEither<Errors, Job> {
  const dto = toCreateDto(job)
  const insertQuery = createInsertQuery('jobs')(dto)

  return pipe(
      insertQuery, // string
      query, // TaskEither<Error, unknown>
      map(() => fromEither(fromDto(dto) // Either<Errors, Job> ))
  ) // TaskEither<Error, TaskEither<Errors, Job>>
}

For the second one after that, adding a flatten after the map doesn't seem to work either.


Solution

  • So, it seems that in the question. One of the left values in the pipe was Error and the other was Errors. Which means there were two paths where different left values could be returned. To make it more clear. I changed the Errors into a type ValidationErrors. And used chainW to be able to merge multiple left errors in one pipe. Resulting in eventually having:

    export function storeJob(job: CreateJob): TaskEither<Error | ValidationErrors, Job> {
      const dto = toCreateDto(job)
      const insertQuery = createInsertQuery('jobs')(dto)
    
      return pipe(
          insertQuery,
          query,
          T.chainW(() => T.fromEither(fromDto(dto)))
      )
    }