You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在fp-ts中合并两个TaskEither实例得到属性覆盖的新对象

实现方案

核心思路

你需要完成两步核心处理:

  • 先将返回ErrorB的TaskEither做错误类型映射,统一为ErrorA,满足最终返回的错误类型要求
  • 使用TaskEither的Applicative实例组合两个异步结果,成功时用对象展开语法合并,B的属性自动覆盖A的同名属性

实现代码

首先导入依赖:

import * as TE from 'fp-ts/TaskEither'
import { liftA2 } from 'fp-ts/Apply'

基础示例

// 定义你的类型
type ErrorA = { type: 'error_a', message: string }
type ErrorB = { type: 'error_b', message: string }
type A = { a: number, b: number, c: number }

// 你的两个原始TaskEither实例
declare const teA: TE.TaskEither<ErrorA, A>
declare const teB: TE.TaskEither<ErrorB, Partial<A>> // 这里约束B是A的部分属性,保证类型安全

// 1. 把ErrorB转换为ErrorA,你可以根据业务逻辑自定义转换规则
const mapErrorBToA = (err: ErrorB): ErrorA => {
  return {
    type: 'error_a',
    message: `依赖任务失败: ${err.message}`
  }
}
const mappedTeB = TE.mapLeft(mapErrorBToA)(teB)

// 2. 定义对象合并逻辑,后传入的对象会覆盖前面对象的同名属性
const mergeObjects = (a: A, b: Partial<A>): A => ({ ...a, ...b })

// 3. 组合两个TaskEither
// 选择ApplyPar:两个任务并行执行,无先后依赖
const resultTe = liftA2(TE.ApplyPar)(mergeObjects)(teA)(mappedTeB)

// 可选:如果需要串行执行,先执行teA成功后再执行teB,替换为ApplySeq即可
// const resultTe = liftA2(TE.ApplySeq)(mergeObjects)(teA)(mappedTeB)

执行效果

按照你给出的示例值:

  • teA成功返回{a: 123, b: 456, c: 0}
  • teB成功返回{c: 789}
    最终resultTe成功时的返回值就是{a: 123, b: 456, c: 789},符合你的预期。
    任意一个TaskEither执行失败时,都会返回转换后的ErrorA类型错误。

内容的提问来源于stack exchange,提问作者AlternatifCoplugu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 02:54:01