如何调整taskEither.tryCatch代码使错误归至Left侧以获得正确类型?
解决方案
问题出在你外层tryCatch的回调逻辑中:当something返回Left时,你直接return result.left,这个值会被tryCatch当作成功结果(Right侧),而非错误(Left侧)。tryCatch仅会把回调中抛出的异常映射到Left,正常返回的所有值都归为Right,这就导致了类型不符合预期。
下面提供两种解决方式:
方式一:抛出Left值让外层捕获
修改外层回调,遇到Left时抛出对应的错误值,让tryCatch将其归入Left侧,同时调整错误处理函数的返回类型以覆盖两种错误:
import * as taskEither from 'fp-ts/TaskEither'; import * as either from 'fp-ts/Either'; const something = taskEither.tryCatch( async () => { const random = Math.random(); if (random < 0.5) throw new Error(); return random < 0.25; }, () => 'innerError' as const, ); const finalTask = taskEither.tryCatch( async () => { const result = await something(); if (either.isLeft(result)) { // 抛出innerError,触发外层tryCatch的错误映射 throw result.left; } if (!result.right) throw new Error(); return result.right; }, (err) => // 判断错误类型,返回联合的错误标识 typeof err === 'string' ? err : 'OuterError' as const, ); // 此时类型为 TaskEither<'innerError' | 'OuterError', true>
方式二:使用chain链式组合(推荐)
这是fp-ts中处理TaskEither链式操作的更符合范式的方式,chain会自动传递Left值:如果上游something是Left,整个结果直接继承该Left;如果是Right,则执行后续逻辑生成新的TaskEither,错误类型会自动合并到Left侧:
import * as taskEither from 'fp-ts/TaskEither'; import * as either from 'fp-ts/Either'; const something = taskEither.tryCatch( async () => { const random = Math.random(); if (random < 0.5) throw new Error(); return random < 0.25; }, () => 'innerError' as const, ); const finalTask = taskEither.chain(something, (val) => // 根据val的值返回成功或新的错误 val ? taskEither.right(true) : taskEither.left('OuterError' as const) ); // 此时类型为 TaskEither<'innerError' | 'OuterError', true>
内容的提问来源于stack exchange,提问作者Florat
相关产品推荐
相关产品推荐

