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

TypeScript条件类型无法识别判别式对象ok状态问题

问题分析:TypeScript泛型状态对象类型错误原因

需求:创建一个对象类型,当status为"ok"时,仅在泛型TData被实例化的情况下存在data键;未实例化TData时,不存在data键。

尝试的代码:

type TStatusObject<TData = never> =
  | { status: 'idle' }
  | { status: 'loading' }
  | { status: 'error'; }
  | (TData extends never ? { status: 'ok', data?: never } : { status: 'ok'; data: TData });

const fooStatus: TStatusObject = { status: 'ok' };

出现的错误提示:

Type '"ok"' is not assignable to type '"idle" | "loading" | "error"'.ts(2322)
status-object.ts(4, 7): The expected type comes from property 'status' which is declared here on type 'TStatusObject'

错误原因

当你省略泛型参数时,TStatusObject会使用默认的never作为TData的类型,此时进入条件分支{ status: 'ok', data?: never }。

TypeScript中,data?: never表示这个属性要么不存在,要么类型是never——但never是没有任何有效值的类型,这意味着这个分支没有合法的实例可以创建。TypeScript会自动优化掉这个“不可实例化”的联合分支,导致最终的TStatusObject类型只剩下{ status: 'idle' } | { status: 'loading' } | { status: 'error' }三种情况,自然不包含status: 'ok'的可能性,因此抛出类型不匹配的错误。

修复方案

把TData extends never对应的分支改成纯粹的{ status: 'ok' }即可,因为此时我们本来就不需要data键:

type TStatusObject<TData = never> =
  | { status: 'idle' }
  | { status: 'loading' }
  | { status: 'error'; }
  | (TData extends never ? { status: 'ok' } : { status: 'ok'; data: TData });

// 验证
const fooStatus: TStatusObject = { status: 'ok' }; // 正常通过类型检查
const fooStatusWithData: TStatusObject<string> = { status: 'ok', data: 'success' }; // 带data的情况也正常

内容的提问来源于stack exchange,提问作者Noitidart

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 08:31:01