为何TypeScript条件类型会影响分支结果?
TypeScript条件类型中联合类型的分发问题
问题场景
使用条件类型时,遇到联合类型导致结果不符合预期:
type Type1<O> = O extends never ? unknown : (undefined extends O ? 1 : 2); type a = Type1<string | undefined> // 实际结果:1 | 2 type Type2<O> = undefined extends O ? 1 : 2; type b = Type2<string | undefined> // 实际结果:1
原本预期a和b类型一致,但实际结果差异明显。
原因分析
核心是条件类型的分布式特性:当条件类型的左侧泛型参数是联合类型时,TypeScript会自动将联合类型拆分为单个成员,分别代入条件计算,最终合并结果为新的联合类型。
针对Type1<string | undefined>:
- 联合类型
string | undefined被拆分为string和undefined两个独立分支; - 处理
string分支:string extends never不成立,进入后续判断undefined extends string,结果为false,返回2; - 处理
undefined分支:undefined extends never不成立,进入后续判断undefined extends undefined,结果为true,返回1; - 最终合并两个分支的结果,得到
1 | 2。
而Type2中,条件左侧是固定类型undefined,泛型参数O在条件右侧,不会触发分布式特性,直接判断undefined是否属于联合类型string | undefined,结果为true,返回1。
解决方案
要避免分布式特性,需将泛型参数包裹在元组中,让联合类型作为整体参与判断:
type Type1<O> = [O] extends [never] ? unknown : (undefined extends O ? 1 : 2); type a = Type1<string | undefined> // 现在结果为1
通过[O] extends [never]的形式,元组会保留联合类型的整体性,不会拆分成员。此时string | undefined作为整体判断不满足extends never,进入后续逻辑后,undefined extends string | undefined为true,最终返回1,符合预期。
内容的提问来源于stack exchange,提问作者Jiří Cihelka
相关产品推荐
相关产品推荐

