给 AI 返回数据加 TS 类型:别全标 any

时间:2026-07-03 08:28:47 来源:互联网

AI接口开发中一个常见误区:将返回值统一标注any类型,流式chunk亦是如此,直至字段错误在运行时暴露。本文基于团队早期实践,总结补齐TypeScript类型时遇到的几个关键问题。

给 AI 返回数据加 TS 类型,别全标 any

先给流式 chunk 定结构

后端每条 SSE data 块的结构是固定的,先将其定义为 interface:

 复制代码interface StreamChunk {
  id: string
  choices: {
    delta: { content?: string; role?: string }
    finish_reason: string | null
  }[]
}

需注意content字段为可选属性。流式传输中,部分chunk仅包含role(如首条数据),另一些只有finish_reason(如末尾数据)。若未标记为可选,类型解析将无法匹配。

parse 后别直接信

JSON.parse的返回值类型为any。直接使用as StreamChunk进行类型断言并不能真正保护代码安全—当后端实际返回结构异常时,类型系统依然默许,运行时错误仍会发生。建议使用zod进行运行时校验,或至少编写守卫函数:

 复制代码function isChunk(x: unknown): x is StreamChunk {
  return typeof x === 'object' && x !== null && 'choices' in x
}

类型断言仅能欺骗编译器,运行时校验才是真正的安全保障,二者不可混淆。

AI 返回结构化数据更要类型

让AI返回JSON(如抽取出的字段)是最具挑战的场景。AI偶尔会遗漏字段,或将数字返回为字符串。针对这类返回定义类型时,建议将所有字段标为可选并设置兜底默认值,确保渲染过程中具备容错能力:

 复制代码interface Extracted {
  name?: string
  amount?: number // AI 可能返回 "100" 字符串,得自己转
}

切勿假设AI会完全遵循给定的schema返回,必须承认其偶发的不可预测性。

给 hook 也标好类型

封装的useChat等hook,其入参、返回的messages及状态机status,应全部标注为字面量联合类型:

 复制代码type Status = 'idle' | 'streaming' | 'error'

status的类型限定为'idle' | 'streaming' | 'error'而非string后,若switch分支遗漏某个状态,编译器会及时提醒,避免大量低级错误。

一个偷懒处

后端接口未能通过OpenAPI工具自动生成类型,而是手动编写interface。当后端字段发生变更时,前端类型无法同步更新,需人工跟进。推荐使用schema进行自动生成,但相关流程尚未搭建。

为流式chunk和结构化数据定义精准类型,并结合运行时校验,可有效规避AI返回数据中的类型陷阱,提升联调效率。如何为AI返回数据建立类型安全保障,值得深入探讨。