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

如何基于_stepResult返回类型推断message参数?改写为()=>T可运行

TypeScript基于返回值推断参数类型的问题

我想要让handleFn中_stepResultFn的message参数类型,能根据_stepResult的返回值自动推断出来。但目前只有把_stepResult的类型定义改成() => T形式时,类型推断才正常工作,以下是我的代码:

type Txt = { type: "message"; text: string; };
type Image = { type: "image"; url: string; };
type TextMessage = { type: 'message'; text: string; };
type ImageMessage = { type: 'image', description: string; url: string; };

type StepMap = {
  message: [Txt, TextMessage];
  image: [Image, ImageMessage];
};

const handleFn = <T extends keyof StepMap>(
  name: string,
  _stepResult: () => StepMap[T][1],
  _stepResultFn: (message: StepMap[T][0]) => StepMap[T][0]
) => {};

const messageStep = handleFn(
  'start',
  () => {
    return {
      type: 'message',
      text: '123'
    };
  },
  ({ type, text }) => {
    return { text, type  };
  }
);

const imageStep = handleFn(
  'image_step',
  () => {
    return {
      type: 'image',
      description: 'img description',
      url: 'test.nl'
    }
  },
  ({ type, url }) => {
    return { url, type };
  }
);

问题原因

原写法中,T被约束为keyof StepMap,但TypeScript无法从_stepResult的返回值反向推导T的具体值——因为StepMap[T][1]是依赖T的类型,类型推断方向不匹配,导致_stepResultFn的参数类型无法正确关联。

解决方案

调整泛型定义逻辑,让handleFn直接从_stepResult的返回类型R入手,通过辅助类型从StepMap中映射出对应的输入类型:

type Txt = { type: "message"; text: string; };
type Image = { type: "image"; url: string; };
type TextMessage = { type: 'message'; text: string; };
type ImageMessage = { type: 'image', description: string; url: string; };

type StepMap = {
  message: [Txt, TextMessage];
  image: [Image, ImageMessage];
};

// 辅助类型:从返回类型R匹配对应的输入类型
type InputFromResult<R> = {
  [K in keyof StepMap]: StepMap[K][1] extends R ? StepMap[K][0] : never
}[keyof StepMap];

const handleFn = <R extends StepMap[keyof StepMap][1]>(
  name: string,
  _stepResult: () => R,
  _stepResultFn: (message: InputFromResult<R>) => InputFromResult<R>
) => {};

const messageStep = handleFn(
  'start',
  () => {
    return {
      type: 'message',
      text: '123'
    };
  },
  ({ type, text }) => { // 参数自动推断为Txt类型
    return { text, type  };
  }
);

const imageStep = handleFn(
  'image_step',
  () => {
    return {
      type: 'image',
      description: 'img description',
      url: 'test.nl'
    }
  },
  ({ type, url }) => { // 参数自动推断为Image类型
    return { url, type };
  }
);

这种写法让TypeScript从_stepResult的返回值R出发,通过InputFromResult类型找到StepMap中对应的输入类型,实现自动推断。你提到的将_stepResult改为() => T的思路,本质也是让泛型从返回值入手,和上述方案逻辑一致。

内容的提问来源于stack exchange,提问作者Jarno van Rhijn

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 20:41:04