You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 07:37:46