TypeScript中泛型传入any比对void为何返回联合类型?
问题原因解析
核心原因是TypeScript条件类型针对any有专门的求值规则:当any出现在extends关键字左侧时,条件表达式不会走常规的子类型判断逻辑,而是直接返回true分支结果和false分支结果的联合类型。
你定义的判断逻辑为两层嵌套条件:
type test<T> = T extends void ? (void extends T ? 1 : 0) : 0;
当传入T = any时,第一层判断any extends void触发any的特殊规则,直接合并两个分支的返回结果:
- true分支结果:
void extends any ? 1 : 0→ 所有类型都可以赋值给any,所以返回1 - false分支结果:直接返回
0
最终合并得到1 | 0,也就是你观察到的联合类型结果。
其他测试结果的逻辑补充:
- 对于
T = never:never是所有类型的子类型,且当extends左侧为never时,条件类型直接返回never,所以结果为never - 对于
T = unknown:unknown是所有类型的父类型,无法赋值给void,第一层判断直接走false分支返回0 - 对于
T = void:两层判断都满足,返回1 - 其他基础类型/对象类型都不满足
T extends void的条件,直接返回0
解决方案
如果需要实现不受any干扰的严格void类型判断,可以使用TS社区通用的全等判断工具类型Equal实现:
// 通用类型全等判断工具 type Equal<X, Y> = (<T>() => T extends X ? 1 : 2) extends (<T>() => T extends Y ? 1 : 2) ? true : false; // 改写后的IsVoid判断 type IsVoid<T> = Equal<T, void> extends true ? 1 : 0; // 验证结果 type v1 = IsVoid<any>; // 0 符合预期 type v2 = IsVoid<unknown>; // 0 type v3 = IsVoid<undefined>; // 0 type v6 = IsVoid<void>; // 1
内容的提问来源于stack exchange,提问作者james
相关产品推荐
相关产品推荐

