如何实现TypeScript的部分分布式条件类型?需单独处理undefined
实现「部分」分布式条件类型:单独处理undefined
当然可行,问题出在你当前的ToArrayOrUndefined利用了条件类型的分布式展开特性,导致非undefined的联合成员被逐个处理,而不是作为整体转换为数组。以下是解决方案和原理说明:
问题原因
当条件类型的泛型参数是裸类型参数(未被数组、元组等包裹)时,TypeScript会自动对联合类型进行分布式展开。你的ToArrayOrUndefined<T>中,T是裸参数,所以传入string | number | undefined时会被拆分为三个独立分支处理:
T=undefined→ 返回undefinedT=string→ 返回string[]T=number→ 返回number[]
最终得到string[] | number[] | undefined,不符合你期望的合并数组结果。
解决方案
我们需要让非undefined的联合成员作为整体传入ToArray,而不是逐个展开。可以通过检查类型是否包含undefined,再结合Exclude工具类型移除undefined成员,最后合并结果:
type ToArray<Type> = [Type] extends [any] ? Type[] : never; // 修改后的类型定义 type ToArrayOrUndefined<T> = undefined extends T ? ToArray<Exclude<T, undefined>> | undefined : ToArray<T>; // 测试验证 type Test1 = ToArray<string | number>; // (string | number)[] (符合预期) type Test2 = ToArray<string | number | undefined>; // (string | number | undefined)[] (符合预期) type Test3 = ToArrayOrUndefined<string | number | undefined>; // (string | number)[] | undefined (符合预期) type Test4 = ToArrayOrUndefined<string | number>; // (string | number)[] (符合预期)
原理说明
undefined extends T:判断泛型T是否包含undefined成员Exclude<T, undefined>:从联合类型T中移除undefined,得到纯非undefined的联合类型ToArray<...>:因为ToArray的参数被元组[Type]包裹,不会触发分布式展开,所以会将整个联合类型转换为对应的数组类型- 最后根据是否包含
undefined,决定是否在结果中加入undefined
内容的提问来源于stack exchange,提问作者RatTac
相关产品推荐
相关产品推荐

