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

如何根据字段类型从TypeScript联合类型中提取指定类型?

解决TypeScript函数根据输入参数精确推断返回类型的问题

当前代码中,sendCommand函数接收OutputActions联合类型参数,但返回值被推断为InputActions联合类型,无法根据传入的command值自动锁定对应的InputAction子类型,导致访问k.token时报错。要实现精确类型推断,可以通过泛型+映射类型来关联输入输出的类型关系:

步骤1:定义类型映射关系

先创建一个映射类型,将command(与action_id值一致)和对应的输入、输出类型绑定:

// 定义命令到对应类型的映射
type ActionMap = {
  start: {
    input: InputAction1;
    output: OutputAction1;
  };
  end: {
    input: InputAction2;
    output: OutputAction2;
  };
};

步骤2:重构sendCommand为泛型函数

利用泛型参数锁定传入的command类型,然后通过映射类型获取对应的返回值类型:

interface OutputAction1 {
  command: 'start';
  params: string;
}

interface OutputAction2 {
  command: 'end';
  data: string;
}

interface InputAction1 {
  action_id: 'start';
  token: string;
}

interface InputAction2 {
  action_id: 'end';
  userData: string;
}

type ActionMap = {
  start: {
    input: InputAction1;
    output: OutputAction1;
  };
  end: {
    input: InputAction2;
    output: OutputAction2;
  };
};

// 泛型函数,C约束为ActionMap的key(即'start'|'end')
const sendCommand = <C extends keyof ActionMap>(action: ActionMap[C]['output']): ActionMap[C]['input'] => {
  if (action.command === 'start') {
    return {
      action_id: 'start',
      token: '123'
    } as ActionMap[C]['input']; // 类型断言确保TS识别分支返回类型
  } else {
    return {
      action_id: 'end',
      userData: '123'
    } as ActionMap[C]['input'];
  }
};

// 现在类型推断正常
let k = sendCommand({ command: 'start', params: '' });
k.token; // 正确识别为InputAction1,无报错

let m = sendCommand({ command: 'end', data: '' });
m.userData; // 正确识别为InputAction2,无报错

原理说明

  • 泛型参数C会根据传入的action.command自动推断为具体的命令值('start'或'end')。
  • ActionMap[C]['output']约束了函数参数必须是对应命令的OutputAction类型,ActionMap[C]['input']则明确了返回值是对应命令的InputAction类型,实现了输入输出类型的精确绑定。
  • 分支中的类型断言是因为TS无法自动将分支返回值与泛型约束的返回类型关联,手动断言后即可消除类型报错。

内容的提问来源于stack exchange,提问作者Kostya Tresko

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 06:05:00