TypeScript:冲突类型交集未返回never,反而得到something?
为什么属性冲突的对象类型交集不是never?
先看你写的代码:
type A = {value: string} type B = {value: number} type D = A & B type E<T> = T extends never ? 'never' : 'something'; type F = E<D> // 预期是'never',实际得到'something'
首先得搞清楚TypeScript里对象类型交集的逻辑:
- 两个对象类型做
&运算时,会把所有属性合并到一起。如果某个属性在两个类型里都存在,该属性的类型会取两个属性类型的交集。 - 这里
value属性的类型是string & number,而string和number是完全不相交的原始类型,所以它们的交集确实是never。但D本身是一个拥有value: never属性的对象类型,不是never类型本身。
然后看E<T>的判断逻辑:T extends never检查的是T是否直接等于never类型。D是一个对象类型(哪怕它的属性值是never),和never不是一回事,所以条件不成立,返回'something'。
如果想判断这种“属性全是never的对象”是否等价于不可实例化的类型,可以换个写法,比如检查所有属性是否都是never:
type AllPropsNever<T> = T extends { [K in keyof T]: never } ? 'never' : 'something'; type F3 = AllPropsNever<D> // 这里会返回'never'
总结一下:
- 对象类型的交集不会直接变成
never,只会把冲突属性的类型变成never,整个类型还是对象类型 - 只有当类型本身就是
never时,T extends never才会触发true分支,带never属性的对象不满足这个条件
内容的提问来源于stack exchange,提问作者Quang Van
相关产品推荐
相关产品推荐

