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

TypeScript中Prop设为never与undefined的差异及AllOrNone类型问题

为什么用never实现全有或全无参数组时错误提示不直观?

先看你的实现代码:

type AllOrNone<T> = Required<T> | Partial<Record<keyof T, never>>;
type BaseArgs = {a: string}
type Group = {b: number; c: number}

type FooArgs = BaseArgs & AllOrNone<Group>;
declare function foo(arg: FooArgs)

foo({
  a: 's',
  b: 5
})

此时TypeScript给出的错误是Type 'number' is not assignable to type 'never',而非预期的“缺少参数c”。但把never换成undefined后,错误提示就变成了预期的“属性c缺失”,原因在于TypeScript处理联合类型分支匹配的逻辑:

用never时的匹配逻辑

FooArgs是BaseArgs和AllOrNone<Group>的交叉类型,对应两个分支的联合:

  1. BaseArgs & Required<Group>:要求必须同时传入b和c
  2. BaseArgs & Partial<Record<keyof Group, never>>:要求b和c要么完全不传,要么类型为never(实际无法赋值)

当你传入{a: 's', b:5}时,TypeScript会依次尝试匹配这两个分支:

  • 第一个分支因缺少c不匹配;
  • 第二个分支中,你传入了b: number,而该分支要求b的类型是never(或不存在),number与never直接类型冲突,这个“属性类型不兼容”的错误优先级更高,TypeScript会直接抛出它,不会回溯到第一个分支提示“缺少c”。

换成undefined后的匹配逻辑

当把AllOrNone<T>改成Required<T> | Partial<Record<keyof T, undefined>>时,第二个分支变为:要求b和c要么完全不传,要么类型为undefined。

此时传入{a: 's', b:5}:

  • 第一个分支依然因缺少c不匹配;
  • 第二个分支中,b: number与undefined类型不兼容,但TypeScript会继续尝试匹配联合类型的其他分支,回到第一个分支后发现缺少c,最终抛出符合预期的“属性c缺失”错误。

简单来说,never的类型冲突优先级更高,直接阻断了TypeScript检查另一个分支的缺失属性;而undefined的类型冲突不会阻断分支匹配,TypeScript会继续尝试其他分支,最终给出更直观的错误提示。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 18:15:02