使用MCP TypeScript SDK迭代messages遇TypeScript类型错误求助
MCP TypeScript SDK遍历messages类型问题解决
问题描述
使用MCP(Model Context Protocol)TypeScript SDK(@modelcontextprotocol/sdk)遍历getPrompt()返回的messages时,即使显式转换为GetPromptResult["messages"]类型,TypeScript仍提示错误:Property 'content' does not exist on type 'string'。预期message类型为包含role和content的对象,但TypeScript将其推断为string类型。
相关代码:
命令提取函数
/** * Checks if the user prompt is a slash command (e.g. "/format deposition.md"), fetches the corresponding MCP prompt, and returns the server-built messages. * Returns null if the query is not a slash command. * @param query User prompt (may start with a "/" command) * @param mcpClient Connected MCP Client instance * @returns Array of PromptMessages from the server, or null if not a command */ export const extractPromptCommand = async (query: string, mcpClient: Client) => { if(!query.startsWith("/")) return null; const [rawCommand, ...argParts] = query.slice(1).split(" "); const command = rawCommand?.trim(); const argument = argParts.join(" ").trim(); if(!command) return null; try { const { messages } = await mcpClient.getPrompt({ name: command, ...(argument && { arguments: { doc_id: argument } }) }) return messages; } catch(error: any) { throw new Error(`Prompt command "/${command}" failed: ${error.message}`); } }
遍历代码
// Handling the "/" commands const promptMessage = await extractPromptCommand(prompt, mcpClient); if(promptMessage) { for (const message in promptMessage as GetPromptResult["messages"]) { const msg = message.content; } }
环境信息:
- @modelcontextprotocol/sdk v1.29.0
- TypeScript 6.0.2
- Node.js 配置"module": "nodenext"
原因分析
for...in的误用:for...in是用来遍历对象的键名的,对于数组来说,它遍历的是数组的索引字符串(比如"0"、"1"),而不是数组的元素本身。所以循环变量message被TypeScript推断为string类型,自然不存在content属性。- 返回值类型未明确:
extractPromptCommand函数没有标注返回值类型,导致TypeScript无法正确推断promptMessage的类型,即使你用as GetPromptResult["messages"]强制转换,也改变不了for...in遍历键名的行为。
正确解决方案
1. 明确函数返回值类型
给extractPromptCommand添加明确的返回值类型,让TypeScript能自动推断后续变量类型,避免不必要的类型断言:
import { Client, GetPromptResult } from '@modelcontextprotocol/sdk'; export const extractPromptCommand = async ( query: string, mcpClient: Client ): Promise<GetPromptResult["messages"] | null> => { if(!query.startsWith("/")) return null; const [rawCommand, ...argParts] = query.slice(1).split(" "); const command = rawCommand?.trim(); const argument = argParts.join(" ").trim(); if(!command) return null; try { const { messages } = await mcpClient.getPrompt({ name: command, ...(argument && { arguments: { doc_id: argument } }) }) return messages; } catch(error: any) { throw new Error(`Prompt command "/${command}" failed: ${error.message}`); } }
2. 使用正确的数组遍历方式
遍历数组要使用遍历元素的方式,比如for...of、forEach或普通for循环:
方式一:for...of循环(推荐)
直接遍历数组元素,TypeScript能正确推断元素类型:
const promptMessage = await extractPromptCommand(prompt, mcpClient); if(promptMessage) { for (const message of promptMessage) { const msgContent = message.content; // 类型正确,无报错 } }
方式二:forEach遍历
利用数组的forEach方法遍历元素:
const promptMessage = await extractPromptCommand(prompt, mcpClient); promptMessage?.forEach(message => { const msgContent = message.content; // 类型正确 });
方式三:普通for循环
通过索引访问数组元素:
const promptMessage = await extractPromptCommand(prompt, mcpClient); if(promptMessage) { for (let i = 0; i < promptMessage.length; i++) { const message = promptMessage[i]; const msgContent = message.content; // 类型正确 } }
内容的提问来源于stack exchange,提问作者Little Thinker
相关产品推荐
相关产品推荐

