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>的交叉类型,对应两个分支的联合:
BaseArgs & Required<Group>:要求必须同时传入b和cBaseArgs & 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
相关产品推荐
相关产品推荐

