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

TypeScript返回类型推断错误:cityAttractions未触发返回值类型校验

TypeScript返回类型推断错误修复

我定义了如下TypeScript类型,但返回类型推断存在错误:当cityAttractions的返回语句返回字符串而非字符串数组时,预期应该触发类型错误,但目前未生效。

原代码

interface Tool<RESULT = any> {
  returnType?: RESULT;
}

type ToolCallWithInferredReturnType<ToolsRecord extends Record<string, Tool>> = {
  [ToolName in keyof ToolsRecord]: ToolsRecord[ToolName]['returnType']
}

export type OnToolCall<ToolsRecord extends Record<string, Tool> = Record<string, Tool>> = 
  (args: { toolCall: { toolName: string } }) => ToolsRecord extends Record<string, Tool>
    ? ToolCallWithInferredReturnType<ToolsRecord>[typeof args['toolCall']['toolName']] 
    : void | Promise<unknown> | unknown;

type Tools = {
  weather: {
    returnType: string;
  }
  cityAttractions: {
    returnType: string[];
  }
}

export const onToolCall: OnToolCall<Tools> = ({ toolCall }) => {
  if (toolCall.toolName === 'weather') {
    return 'Weather information was shown to the user.';
  }
  if (toolCall.toolName === 'cityAttractions') {
    return "Attractions was shown to the user."; // 此处应该触发类型错误,但未生效
  }

  throw Error("")
}

问题原因

原OnToolCall类型的条件判断ToolsRecord extends Record<string, Tool>始终为真,导致返回类型被推断为ToolCallWithInferredReturnType<Tools>[string],也就是string | string[]联合类型。TypeScript认为返回字符串或字符串数组都是合法的,因此不会触发错误。

修复方案

将OnToolCall改为泛型函数类型,让TypeScript根据传入的toolName字面量类型,精准推断对应的返回类型:

interface Tool<RESULT = any> {
  returnType?: RESULT;
}

type ToolCallWithInferredReturnType<ToolsRecord extends Record<string, Tool>> = {
  [ToolName in keyof ToolsRecord]: ToolsRecord[ToolName]['returnType']
}

// 修改为泛型函数类型,ToolName 对应具体的工具名称字面量
export type OnToolCall<ToolsRecord extends Record<string, Tool>> = 
  <ToolName extends keyof ToolsRecord>(args: { toolCall: { toolName: ToolName } }) => 
    ToolCallWithInferredReturnType<ToolsRecord>[ToolName];

type Tools = {
  weather: {
    returnType: string;
  }
  cityAttractions: {
    returnType: string[];
  }
}

export const onToolCall: OnToolCall<Tools> = ({ toolCall }) => {
  if (toolCall.toolName === 'weather') {
    return 'Weather information was shown to the user.'; // 合法
  }
  if (toolCall.toolName === 'cityAttractions') {
    return "Attractions was shown to the user."; // 现在会触发类型错误:类型"string"不能赋值给类型"string[]"
  }

  throw Error("")
}

效果说明

修改后,当toolCall.toolName为cityAttractions时,TypeScript会推断出返回类型必须是string[],此时返回字符串就会触发预期的类型错误,符合需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 11:37:28