TypeScript递归链式验证Pipeline类型实现求助
TypeScript 递归链式任务管道类型实现
问题根源
你当前的实现失效原因在于:
- 手动传入
Task<any, any>[]作为泛型参数,相当于用any绕过了所有类型校验 ValidateChain的递归逻辑没有正确传递前一个任务的输出类型,无法约束后续任务的输入
可行实现方案
我们需要定义递归类型来逐个校验任务链的输入输出匹配,同时让TypeScript自动推导任务类型,而非手动指定模糊的any类型。
1. 核心递归校验类型
// 递归校验任务链的输入输出匹配关系 type ValidPipeline<Tasks extends Task<any, any>[], PrevOutput = unknown> = Tasks extends [] ? Tasks // 空管道合法 : Tasks extends [Task<infer Input, infer Output>, ...infer RestTasks] ? [Input] extends [PrevOutput] // 当前任务输入是否匹配前一个任务的输出 ? RestTasks extends Task<any, any>[] ? [Task<Input, Output>, ...ValidPipeline<RestTasks, Output>] // 递归校验剩余任务,传递当前输出作为下一个的输入约束 : never : never : never; // 管道类型,接受任务数组并触发校验 export type Pipeline<T extends Task<any, any>[]> = ValidPipeline<T, unknown>;
2. 正确使用方式(自动推导类型)
不需要手动指定泛型参数,让TypeScript自动推导任务数组的具体类型,才能触发校验逻辑:
// 错误示例:类型不匹配会直接报错 const badPipeline: Pipeline<typeof badPipeline> = [ new Task(pipelineItem1, 'pipelineItem1'), new Task(pipelineItem2, 'pipelineItem2'), // 报错:"{ usernamxe: string; password: string; }" 无法赋值给 "{ username: string; userId: number; }" ]; // 正确示例:类型匹配通过 const goodPipeline: Pipeline<typeof goodPipeline> = [ new Task(pipelineItem1, 'pipelineItem1'), new Task(goodPipelineItem2, 'goodPipelineItem2'), ]; async function pipelineItem1(data: { username: string; password: string }) { return { username: data.username, userId: 123, }; } async function pipelineItem2(data: { usernamxe: string; password: string }) { return { username: data.usernamxe, userIssd: 123, }; } async function goodPipelineItem2(data: { username: string; userId: number }) { return { userId: data.userId, token: 'abc123', }; }
3. 简化写法:辅助函数创建管道
可以封装一个辅助函数,避免重复写Pipeline<typeof xxx>:
function createPipeline<T extends Task<any, any>[]>(tasks: ValidPipeline<T, unknown>) { return tasks; } // 直接创建管道,自动校验类型 const pipeline = createPipeline([ new Task(pipelineItem1, 'pipelineItem1'), new Task(goodPipelineItem2, 'goodPipelineItem2'), // 合法 // new Task(pipelineItem2, 'pipelineItem2'), // 此处会直接报错 ]);
关键逻辑说明
- 递归类型
ValidPipeline通过PrevOutput参数传递前一个任务的输出类型,强制后续任务的输入必须匹配该类型 - 依赖TypeScript自动推导任务数组的具体类型,而非手动用
any模糊约束 - 只要任务链中任意一个任务的输入与前一个输出不匹配,类型就会变为
never,触发TypeScript报错
内容的提问来源于stack exchange,提问作者fl45h97
相关产品推荐
相关产品推荐

