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
相关产品推荐
相关产品推荐

