用 TypeScript 拦截 AI 写错的 React 导入
教程用最小 TypeScript 样例检查依赖导出边界,例如识别将 createPortal 错从 react 导入的问题。它强调用已知错误验证检查确实失败,避免测试文件未参与编译却误报通过。
AI 深度解读
AI 生成的 React 代码,可能认得 API,却认错它所属的包。比如 createPortal 确实存在,但应该从 react-dom 导入,写进 react 的导入语句就会出错。原文给出的方法很小:用一个独立的 TypeScript 文件,专门验证这些导入能否成立。
更有价值的是验证方式:先让正确代码通过,再故意放入错误导入,确认检查确实报错。它适合加入 AI 编程的验收流程,但只能证明包的导出边界,不能证明功能已经做好。
API 名字没编错,导入也可能是错的
原文选了三个标准 React API:Fragment、useState 来自 react,createPortal 来自 react-dom。它们经常出现在同一个功能里,却不属于同一个公开入口。

作者记录的验证环境是 React 和 React DOM 19.2.8、TypeScript 5.9.3。在这个环境中,把 createPortal 从 react 导入,会触发 TS2724,提示该模块没有这个具名导出。
遇到这种错误,应先修正包入口。用 any、@ts-ignore 或自己补一份模块声明,都可能让错误从检查结果里消失,却没有解决真实依赖的导出问题。
原文也交代了证据范围:教程由 OpenAI Codex 起草,示例执行过 TypeScript 检查。这是受控复现,不是作者的一次真实排障经历,也没有测量任何 Agent 的错误率。
怎么用一个小文件,把导入变成可验证的事实
在现有 React/TypeScript 项目里,新建 react-import-audit.ts,只放当前功能需要确认的 API:
import { Fragment, useState } from "react";
import { createPortal } from "react-dom";
void [Fragment, useState, createPortal];
注意最后一行:它引用这些值,但没有调用 useState,因此没有在组件外执行 Hook。这个文件也不渲染界面,目的只是让编译器解析准确的包导出。
如果从空项目开始,原文使用 pnpm add react@latest react-dom@latest 和 pnpm add -D typescript @types/react @types/react-dom 安装依赖,并要求保留 lockfile。这里的 latest 是安装指令,不能据此认定之后安装的版本仍然是上述实测版本。
为了避免检查时拉进整个应用的路由和其他代码,再创建专用配置 tsconfig.react-audit.json:
{
"compilerOptions": {
"target": "ES2022",
"module": "ESNext",
"moduleResolution": "bundler",
"lib": ["ES2022", "DOM", "DOM.Iterable"],
"types": ["react", "react-dom"],
"strict": true,
"skipLibCheck": true,
"noEmit": true
},
"include": ["react-import-audit.ts"]
}
最该确认的是 include:它必须包含刚才的检查文件。随后执行 pnpm exec tsc -p tsconfig.react-audit.json。
这里 noEmit 阻止生成 JavaScript;skipLibCheck 跳过声明文件内部的检查,但不会跳过检查文件里的导入。moduleResolution: "bundler" 适用于原文的打包型 React 示例,实际应用仍应使用框架支持的配置。若报错是依赖缺失,先核对安装情况和工作目录,别急着调整编译选项。
为什么通过一次,还不足以验收
命令没有报错,可能是代码正确,也可能是目标文件根本没被编译。
作者因此要求完成一轮验证:正确导入先通过;接着把 createPortal 移到 react 的导入语句里,删除它的 react-dom 导入,确认出现 TS2724;最后恢复正确代码,再确认通过。
检查能发现一个已知错误,才更有理由相信它覆盖了目标文件。
这一步就是失败对照:主动放进一个确定有问题的输入,观察检查是否真的会拒绝它。
作者还建议把它写进 Agent 的验收条件:修改 React 导入前,检查已安装包的公开导出和当前文档;保留小型检查文件;证明检查能捕获一次错误导出;最后运行应用原有的类型检查和生产构建。依赖升级后,也应重新执行,不能把旧版本的结果当成长期保证。
我的判断
这套方法适合处理一种具体的不确定性:AI 写出的导入看起来很熟悉,但没人确认过它是否属于当前安装的包。小文件缩短了验证路径,也方便定位问题。
不过,原文没有提供与直接运行全项目类型检查相比的耗时、检出率或维护成本数据。把它作为团队默认流程是否划算,仍是经验判断。如果现有类型检查已经稳定覆盖所有相关文件,这个独立检查的额外收益需要结合项目判断。
边界也很明确:它没有渲染 portal,没有验证目标 DOM 节点、事件传播、包体积或可访问性。声明检查通过,也不能保证运行时代码与发布的类型完全一致。真正的功能验收仍需要构建、运行时测试和交互检查。
能拿来做什么
- 接受 AI 生成的 React 功能前,把不确定的导入放进小型检查文件,用项目当前安装的依赖验证它们。
- 第一次接入这项检查时,故意制造一次错误包导入,确认命令会失败,再恢复正确代码,避免检查范围配错。
- 在 Agent 指令中明确要求修正导出错误,禁止用
any、@ts-ignore或伪造模块声明掩盖问题,并保留应用原有的类型检查与生产构建。 - 升级 React 或相关类型包后,重新运行检查,并通过 lockfile 保留依赖解析结果,让后续验证有据可查。