如何配置TypeScript,使is类型守卫结合never时正确推断判别式联合?
fp-ts Either 类型推断异常的解决方法
核心问题原因
你的场景里,TypeScript本该识别到if (E.isLeft(result))分支调用返回never的fail函数后,后续代码只会处理Right类型的result,但报错说明控制流分析没生效。这通常和以下两点有关:要么是fail函数的类型定义不严谨,要么是当前TypeScript版本对never分支的控制流分析存在局限,或是fp-ts的isLeft类型守卫和TS的结合细节问题。
具体解决方法
1. 确保fail函数的类型正确定义
先检查你的fail函数是否明确标注返回never,这是TS识别分支不可达的关键:
function fail(message: string): never { throw new GenericProgramError(message); }
如果函数没有显式标注never,TS可能无法正确推断该分支不会执行到后续代码。
2. 使用自定义断言函数(推荐)
自定义一个断言函数,直接在类型守卫里完成错误抛出,让TS明确后续代码的类型:
import * as E from 'fp-ts/Either'; function assertIsRight<E, T>(either: E.Either<E, T>): asserts either is E.Right<T> { if (E.isLeft(either)) { fail(`处理失败: ${either.left}`); } } // 使用示例 const result: E.Either<Error, string> = /* 你的Either结果 */; assertIsRight(result); // 这里TS会正确推断result为Right类型,可安全访问right属性 console.log(result.right);
3. 手动类型断言(快速临时方案)
如果不想修改现有逻辑,也可以直接对result做类型断言,强制TS识别其为Right类型:
if (E.isLeft(result)) { fail(`错误: ${result.left}`); } // 手动断言为Right类型 const rightValue = (result as E.Right<你的右值类型>).right;
4. 升级TypeScript版本
如果你的TS版本低于4.0,建议升级到4.5及以上版本——旧版本的TS对never返回值的控制流分析不够完善,升级后大概率能自动解决这个推断问题。
内容的提问来源于stack exchange,提问作者Adam A
相关产品推荐
相关产品推荐

