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

如何调整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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 00:03:14