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

如何让TypeScript条件never类型更具可用性并返回错误详情?

让TypeScript返回类型校验失败的具体原因而非never

在TypeScript中,直接返回never会丢失校验失败的具体上下文。可以通过**标记类型(Branded Type)**在保留never特性的同时携带错误信息,或者使用联合类型直接暴露错误字符串。以下是具体实现:

方案1:标记类型(兼容原有never逻辑)

通过将never与带有错误信息的对象类型交叉,既保留never的“不可赋值”特性,又能让编译器显示错误详情:

// 定义带错误信息的标记never类型
type Never<Msg extends string> = never & { __error: Msg };

type CheckSmallDog<T> = 
  // 匹配SmallDog,返回正常类型
  T extends SmallDog ? SmallDog :
  // 匹配有woof但不是SmallDog的类型,返回对应错误
  T extends { woof: unknown } ? Never<'not-smalldog'> :
  // 不匹配狗的类型,返回对应错误
  Never<'not-dog'>;

type Animal = {};

interface Cat extends Animal {
  meow(): void;
}

interface SmallDog extends Animal {
  woof(): void;
}

interface BigDog extends Animal {
  bark(): void;
}

// 编译器会显示具体错误信息:
type BigDogCheck = CheckSmallDog<BigDog>; // never & { __error: 'not-dog' }
type SmallDogCheck = CheckSmallDog<SmallDog>; // SmallDog
type CatCheck = CheckSmallDog<Cat>; // never & { __error: 'not-dog' }
type FakeDogCheck = CheckSmallDog<{ woof: void }>; // never & { __error: 'not-smalldog' }

原理

never与任何类型交叉后结果仍为never,因此原有类型系统中依赖never触发的编译报错逻辑完全不受影响。但TypeScript会保留交叉类型的元信息,当鼠标悬停在类型别名上时,就能看到__error字段中的具体原因。

方案2:联合类型(直观显示错误字符串)

如果原有系统不严格依赖never类型,可以直接将错误字符串与never联合,让编译器直接显示错误信息:

type Never<Msg extends string> = never | Msg;

type CheckSmallDog<T> = 
  T extends SmallDog ? SmallDog :
  T extends { woof: unknown } ? Never<'not-smalldog'> :
  Never<'not-dog'>;

// 编译器显示:
type BigDogCheck = CheckSmallDog<BigDog>; // 'not-dog'
type FakeDogCheck = CheckSmallDog<{ woof: void }>; // 'not-smalldog'

注意点

这种方案下,错误类型不再是严格的never,而是字符串字面量类型。如果原有系统通过never来限制参数传递(比如函数参数不接受never),需要评估是否会影响现有逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 00:17:28