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

如何为多Payload类型的Switch Case参数添加TypeScript类型?

多Handler场景下的TypeScript Payload类型约束方案

场景代码

public async handle(
  handler: WorkflowHandlerOption,
  payload: <how_to_type_it?>,
): Promise<StepResponseInterface> {
  switch (handler) {
    case WorkflowHandlerOption.JOB_APPLICATION_ACTIVITY: {
      const {
        entity_id: jobApplicationEntityId,
        status: jobApplicationStatus,
      } = await this.jobApplicationActivityHandler.execute(payload);
      // ...other staff
      break;
    }
    case WorkflowHandlerOption.BILLING_FEE: {
      const { entity_id: billingFeeId, status: billingFeeStatus } =
        await this.billingFeeHandler.execute(payload);
      // ...other staff
      break;
    }
    case WorkflowHandlerOption.DOCUMENT_GENERATION: {
      const { entity_id: documentId, status: documentStatus } =
        await this.documentGenerationHandler.execute(payload);
      // ...other staff
      break;
    }
    case WorkflowHandlerOption.UPDATE_JOB: {
      const { entity_id: jobId, status: jobStatus } =
        await this.jobHandler.execute(payload);
      // ...other staff
      break;
    }
    case WorkflowHandlerOption.DOCUMENT_GENERATION_ACTIVITY: {
      const {
        entity_id: documentActivityId,
        status: documentActivityStatus,
      } = await this.documentGenerationActivityHandler.execute(payload);
      // ...other staff
      break;
    }
    
    default:
      throw new BadRequestException('Handler not found');
  }

  // ...other staff
}

需求说明

现有多个接收不同Payload的handler,需要为payload参数添加TypeScript类型定义,后续将扩展至近50个case场景,要求不依赖第三方库,仅通过TS原生类型实现。

解决方案

1. 定义各Handler对应的Payload类型

先为每个handler创建专属的Payload接口,明确字段结构:

// 示例Payload定义,根据实际业务字段调整
interface JobApplicationActivityPayload {
  applicantId: string;
  jobId: string;
}

interface BillingFeePayload {
  invoiceId: string;
  amount: number;
}

interface DocumentGenerationPayload {
  templateId: string;
  recipient: { name: string; email: string };
}

interface UpdateJobPayload {
  jobId: string;
  status: 'open' | 'closed';
}

interface DocumentGenerationActivityPayload {
  activityId: string;
  documentType: 'contract' | 'offer';
}

2. 创建Handler与Payload的映射关系

用TS的映射类型将WorkflowHandlerOption枚举值与对应Payload绑定,形成类型映射表:

type HandlerPayloadMap = {
  [WorkflowHandlerOption.JOB_APPLICATION_ACTIVITY]: JobApplicationActivityPayload;
  [WorkflowHandlerOption.BILLING_FEE]: BillingFeePayload;
  [WorkflowHandlerOption.DOCUMENT_GENERATION]: DocumentGenerationPayload;
  [WorkflowHandlerOption.UPDATE_JOB]: UpdateJobPayload;
  [WorkflowHandlerOption.DOCUMENT_GENERATION_ACTIVITY]: DocumentGenerationActivityPayload;
};

3. 用泛型实现类型关联(适合大量扩展场景)

将handle方法改为泛型方法,让TS根据传入的handler自动推断payload的类型,无需写大量重载签名:

public async handle<T extends WorkflowHandlerOption>(
  handler: T,
  payload: HandlerPayloadMap[T]
): Promise<StepResponseInterface> {
  switch (handler) {
    case WorkflowHandlerOption.JOB_APPLICATION_ACTIVITY: {
      // 此时payload自动推断为JobApplicationActivityPayload类型
      const { entity_id: jobApplicationEntityId, status: jobApplicationStatus } =
        await this.jobApplicationActivityHandler.execute(payload);
      // ...其他逻辑
      break;
    }
    case WorkflowHandlerOption.BILLING_FEE: {
      // payload自动推断为BillingFeePayload类型
      const { entity_id: billingFeeId, status: billingFeeStatus } =
        await this.billingFeeHandler.execute(payload);
      // ...其他逻辑
      break;
    }
    // 其余case同理
    case WorkflowHandlerOption.DOCUMENT_GENERATION:
    case WorkflowHandlerOption.UPDATE_JOB:
    case WorkflowHandlerOption.DOCUMENT_GENERATION_ACTIVITY: {
      // 对应类型会自动匹配
      // ...逻辑
      break;
    }
    
    default:
      throw new BadRequestException('Handler not found');
  }

  // ...其他逻辑
}

4. 扩展新Handler的流程

后续新增handler时,只需完成3步:

  • 新增对应Payload接口
  • 在HandlerPayloadMap中添加枚举值与Payload的映射关系
  • 在switch中新增对应的case分支
    TS会自动完成类型推断和校验,无需额外配置。

可选:用重载签名提升调用时的类型提示

如果希望调用handle方法时,IDE能更直观地展示每个handler对应的Payload结构,可以添加重载签名:

// 重载签名:为每个handler明确参数组合
public async handle(handler: WorkflowHandlerOption.JOB_APPLICATION_ACTIVITY, payload: JobApplicationActivityPayload): Promise<StepResponseInterface>;
public async handle(handler: WorkflowHandlerOption.BILLING_FEE, payload: BillingFeePayload): Promise<StepResponseInterface>;
public async handle(handler: WorkflowHandlerOption.DOCUMENT_GENERATION, payload: DocumentGenerationPayload): Promise<StepResponseInterface>;
// 其余handler的重载签名...

// 实现签名:复用泛型或联合类型
public async handle<T extends WorkflowHandlerOption>(
  handler: T,
  payload: HandlerPayloadMap[T]
): Promise<StepResponseInterface> {
  // 原switch逻辑
}

这种方式在调用时,选择不同的handler后,IDE会自动提示对应的Payload字段,但需要为每个新handler添加重载行,适合handler数量中等的场景;如果是50+的场景,泛型方式更简洁。


内容的提问来源于stack exchange,提问作者George Hutanu

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 14:10:34