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

优化TypeScript的Result条件类型时,fail函数出现类型不兼容错误

优化TypeScript的Result条件类型时,fail函数出现类型不兼容错误

我来帮你拆解这个问题的根源,以及对应的解决方案:

首先,咱们先看报错的原因:你的fail函数返回类型是Result<never, E>,用你原来的条件类型定义,当E不是never时,这个Result<never, E>会被解析成Success<never> | Failure<E>。虽然Success<never>在实际运行中根本没法构造(因为value是never类型,没有任何值能匹配),但TypeScript的类型检查器会严格遵循你定义的类型规则,认为你返回的Failure<E>没有覆盖Success<never>这个分支,所以抛出了类型不兼容的错误。

而你的succeed函数之所以没问题,是因为它返回的是Result<T, never>,刚好匹配到条件类型里的第一个分支,直接返回Success<T>,和函数返回值完全对应,所以类型校验能通过。

解决方案:调整Result的条件类型,同时处理T为never的场景

我们可以给Result的条件类型再加一个分支,专门处理T为never的情况,这样fail函数的返回类型就能准确匹配Failure<E>了:

type Success<T> = { success: true, value: T }
type Failure<E> = { success: false, error: E }

type Result<T, E = never> = 
  // 当E是never时,只返回Success<T>(对应succeed的场景)
  [E] extends [never] ? Success<T> :
  // 当T是never时,只返回Failure<E>(对应fail的场景)
  [T] extends [never] ? Failure<E> :
  // 其他情况返回成功/失败的联合类型
  Success<T> | Failure<E>

function succeed<T>(value: T): Result<T, never> {
    return { success: true, value }
}
function fail<E>(error: E): Result<never, E> {
    return { success: false, error } // 现在类型校验完全通过
}

function test(value: string): Result<string, string> {
    if (!value) { // 原代码里value是string类型,不会是undefined,这里调整成更合理的空值判断
        return fail("empty");
    } else {
        return succeed(value);
    }
}

额外说明

这里用[E] extends [never]而不是直接E extends never,是为了避免条件类型的分配性问题。如果E是联合类型的话,直接E extends never会把联合类型拆开来逐个判断,而用元组包裹后,会把整个E作为一个整体来判断,这是TypeScript里处理条件类型的常用小技巧。

备注:内容来源于stack exchange,提问作者Faz

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.15 09:43:09