如何将fp-ts的Either类型转为Promise类型并解决类型报错
问题描述
我需要实现带参数校验的HTTP请求逻辑,具体要求:
- 参数校验失败时抛出
parameter invalid错误,直接终止后续执行; - API响应的
code不等于'0'时,抛出res.message里的错误,否则返回完整响应对象; - 在
main函数里用try...catch捕获所有上述错误,并且能在try块里正常访问res.result。
但目前getArticlesByPageService的返回值类型是E.Either<Error, ApiResponse<any>>,直接访问res.result会报错:
Property 'result' does not exist on type 'Either<Error, ApiResponse
>'. Property 'result' does not exist on type 'Left '
请问怎么把这个Either类型转换成Promise<ApiResponse<any>>类型?
解决方案
1. 编写Either转Promise的工具函数
Either类型的核心逻辑是左值(Left)存储错误、右值(Right)存储成功结果,我们可以写一个通用转换函数,将其与Promise的错误/成功流对齐:
import { Either, isLeft, isRight } from 'fp-ts/Either'; function eitherToPromise<T>(either: Either<Error, T>): Promise<T> { if (isLeft(either)) { // Left中的错误直接通过Promise.reject抛出 return Promise.reject(either.left); } else { // Right中的结果通过Promise.resolve返回 return Promise.resolve(either.right); } }
2. 整合参数校验与API调用逻辑
先完成参数校验,通过后调用服务并转换为Promise,最后处理API响应的code规则:
// 定义API响应的类型结构 interface ApiResponse<T> { code: string; message: string; result: T; } // 参数校验函数,根据实际业务需求调整校验规则 function validateParams(params: any): void { if (!params.page || params.page <= 0 || !params.size || params.size <= 0) { throw new Error('parameter invalid'); } } // 封装完整的请求逻辑 async function fetchArticles(params: any): Promise<ApiResponse<any>> { // 先执行参数校验,失败直接抛错终止流程 validateParams(params); // 调用服务并将Either转换为Promise const eitherRes = await getArticlesByPageService(params); const res = await eitherToPromise(eitherRes); // 校验API响应code,非0则抛出对应错误 if (res.code !== '0') { throw new Error(res.message); } return res; }
3. 在main函数中使用try/catch处理
现在可以正常用try...catch捕获所有错误,且能直接访问res.result:
async function main() { try { const reqParams = { page: 1, size: 10 }; const response = await fetchArticles(reqParams); // 类型已确定为ApiResponse,可直接访问result console.log('文章列表:', response.result); } catch (error) { // 统一捕获所有错误:参数校验失败、服务返回的Left错误、响应code非0的错误 console.error('请求出错:', error.message); } } main();
关键说明
- 使用
fp-ts自带的isLeft/isRight作为类型守卫,能让TypeScript正确识别Either的具体类型,避免类型报错; - 转换后的Promise自动将Either的错误流映射到Promise的reject,成功流映射到resolve,完美适配
try...catch的错误捕获逻辑; - 参数校验、服务错误、响应code校验的所有错误都会被统一捕获,无需单独处理每个环节的异常。
内容的提问来源于stack exchange,提问作者Lin Du
相关产品推荐
相关产品推荐

