如何将泛型与可变参数结合,实现多BaseResponse合并函数?
如何将BaseResponse合并函数改为支持任意数量参数
调整后的函数签名与类型辅助
首先需要定义一个辅助类型来将元组中的所有类型交叉合并,再结合可变元组泛型实现任意数量参数的支持:
type BaseResponse<T> = { success: boolean; data?: T; }; // 辅助类型:将元组内的所有类型转换为交叉类型 type TupleToIntersection<T extends unknown[]> = T extends [infer First, ...infer Rest] ? First & TupleToIntersection<Rest> : unknown; // 支持任意数量参数的zip函数签名 function zip<T extends unknown[]>(...responses: { [K in keyof T]: BaseResponse<T[K]> }): BaseResponse<TupleToIntersection<T>>;
签名说明
T extends unknown[]:声明T为任意类型的元组,对应每个传入BaseResponse的data类型集合。...responses: { [K in keyof T]: BaseResponse<T[K]> }:通过映射类型,将元组T的每个元素转换为对应的BaseResponse类型,确保传入参数均为合法响应对象。- 返回值
BaseResponse<TupleToIntersection<T>>:将元组T中的所有类型交叉合并,作为最终响应的data类型。
完整实现代码
基于循环逻辑实现,保留原函数核心行为:只要有一个响应失败,最终结果标记为失败且不返回data。
type BaseResponse<T> = { success: boolean; data?: T; }; type TupleToIntersection<T extends unknown[]> = T extends [infer First, ...infer Rest] ? First & TupleToIntersection<Rest> : unknown; function zip<T extends unknown[]>(...responses: { [K in keyof T]: BaseResponse<T[K]> }): BaseResponse<TupleToIntersection<T>> { let success = true; const data: Partial<TupleToIntersection<T>> = {}; for (const res of responses) { if (!res.success) { success = false; } else if (res.data) { Object.assign(data, res.data); } } return { success, data: success ? (data as TupleToIntersection<T>) : undefined, }; }
使用示例
// 成功合并多个响应 const res1: BaseResponse<{ id: number }> = { success: true, data: { id: 1 } }; const res2: BaseResponse<{ name: string }> = { success: true, data: { name: "Alice" } }; const res3: BaseResponse<{ age: number }> = { success: true, data: { age: 30 } }; const combined = zip(res1, res2, res3); // combined 类型为 BaseResponse<{ id: number } & { name: string } & { age: number }> console.log(combined.data); // { id: 1, name: "Alice", age: 30 } // 包含失败响应的情况 const failedRes: BaseResponse<{ email: string }> = { success: false }; const combinedFailed = zip(res1, failedRes); console.log(combinedFailed.success); // false console.log(combinedFailed.data); // undefined
内容的提问来源于stack exchange,提问作者Gustavo L.
相关产品推荐
相关产品推荐

