以某种方式结束 Promise<Either<Errors, Job>> 而不是 TaskEither<Errors, Job>

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

我对 FP-TS(或一般的函数式编程)还不是很满意,所以我可能在这里做错了一些事情。

我有以下功能,我想 return TaskEither<Errors, Job> 但我似乎无法让它工作。

这个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>>
}

再次尝试(只更改了最后一个管道,添加了 map)我做了 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>>
}

之后的第二个,在地图后面加一个flatten好像也不行。

所以,好像在题中。管道中的 left 值之一是 Error,另一个是 Errors。这意味着有两条路径可以返回不同的左值。为了更清楚。我将错误更改为 ValidationErrors 类型。并使用 chainW 能够在一个管道中合并多个左错误。最终导致:

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)))
  )
}