如何在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
相关产品推荐
相关产品推荐

