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

如何让TypeScript函数根据传入参数动态匹配返回类型?

问题描述

现有如下4个类:

class PutCommand {
   // TODO
}

class PutCommandOutput {
   // TODO
}

class DeleteCommand {
   // TODO
}

class DeleteCommandOutput {
   // TODO
}

需要实现一个executeCommand函数,接受PutCommand或DeleteCommand实例作为参数,返回对应的PutCommandOutput或DeleteCommandOutput类型。

最初的实现返回联合类型,调用后必须手动判断返回值类型:

function executeCommand(command: PutCommand|DeleteCommand): PutCommandOutput|DeleteCommandOutput {
   // TODO:
}

调用示例:

const output = executeCommand(command);

if (output instanceof PutCommandOutput) {
  // 处理PutCommandOutput逻辑
} else {
  // 处理DeleteCommandOutput逻辑
}

尝试泛型写法后,仍需显式指定返回类型,不够便捷:

function executeCommand<T>(command: PutCommand|DeleteCommand): T {
   // TODO:
}

调用示例:

const output = executeCommand<DeleteCommandOutput>(command);

希望实现更智能的类型推导:传入PutCommand实例时,返回类型自动为PutCommandOutput,无需手动指定或判断,直接调用对应类的方法。

解决方案

有两种常用方式可以实现自动类型推导:

方式一:函数重载

通过定义函数重载签名,让TypeScript根据传入的参数类型自动匹配返回类型:

// 重载签名:定义不同参数对应的返回类型
function executeCommand(command: PutCommand): PutCommandOutput;
function executeCommand(command: DeleteCommand): DeleteCommandOutput;

// 函数实现
function executeCommand(command: PutCommand | DeleteCommand): PutCommandOutput | DeleteCommandOutput {
  // 实际执行逻辑
  if (command instanceof PutCommand) {
    return new PutCommandOutput();
  } else {
    return new DeleteCommandOutput();
  }
}

方式二:类型映射+泛型

先定义命令与输出的类型映射关系,再通过泛型关联参数与返回值类型,扩展性更强:

// 定义命令到输出的类型映射
type CommandOutputMap = {
  [Command in PutCommand | DeleteCommand]: 
    Command extends PutCommand ? PutCommandOutput : DeleteCommandOutput;
};

// 泛型函数实现
function executeCommand<T extends PutCommand | DeleteCommand>(command: T): CommandOutputMap[T] {
  if (command instanceof PutCommand) {
    return new PutCommandOutput() as CommandOutputMap[T];
  } else {
    return new DeleteCommandOutput() as CommandOutputMap[T];
  }
}

效果验证

调用时无需额外操作,TypeScript会自动推导返回类型:

const putCmd = new PutCommand();
const putOutput = executeCommand(putCmd); // putOutput 类型自动推导为 PutCommandOutput
// 可直接调用PutCommandOutput的方法

const deleteCmd = new DeleteCommand();
const deleteOutput = executeCommand(deleteCmd); // deleteOutput 类型自动推导为 DeleteCommandOutput
// 可直接调用DeleteCommandOutput的方法

内容的提问来源于stack exchange,提问作者Wai Yan Hein

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 22:35:32