TypeScript 类型推断 + JSDoc 可在不改写 JavaScript 的前提下提供强类型提示、编辑器补全与跳转支持,并自动生成可读文档;核心是复用 TS 类型能力为 JS 注入静态防御力。
用 TypeScript 类型推断 + JSDoc,能在不改写 JavaScript 的前提下,让关键变量、函数参数和返回值获得强类型提示、编辑器补全、跳转支持,同时自动生成可读文档。核心不是“替代 TS”,而是把 TS 的类型能力借过来,为 JS 注入静态防御力。
后端 API 响应、表单序列化结果这类运行时生成的对象,纯 JSDoc 很难准确描述。解决办法是:
types/api.d.ts 中定义响应类型,比如 interface ProductListResponse { items: Product[]; total: number; }
/** @type {import('./types/api').ProductListResponse} */ 显式标注变量"js/ts.implicitProjectConfig.checkJs": true 设置,编辑器立刻能校验字段是否存在、类型是否匹配角色、状态码、配置键名这类字符串常量,不能只标 string,否则失去约束力。正确做法是:
as const 定义数组或对象,例如:const STATUSES = ["draft", "published", "archived"] as const;
export type Status = typeof STATUSES[number]; // "draft" | "published" | "archived"
/** @type {Status} */ let status = "draft"; —— 编辑器会阻止你赋值为 "pending" 这类非法值as const 默认只做浅层只读,深层属性仍可能被意外修改。JSDoc 本身不改变运行时行为,所以必须靠类型定义兜底:
const config = { api: { url: "..." } } as const; → config.api.url = "hacked" 在 TS 中报错,但 JS 运行时仍可执行as const,再通过 @type 引用完整类型,例如:/** @type {{ api: { url: string } & { readonly url: string } }} */
.d.ts 中,用 import() 引入,类型清晰且 IDE 支持完整JSDoc 注释不只是给机器看的,更是给人读的。一个带类型标注的函数注释,本身就是接口说明书:
/** * 获取用户订单列表 * @param {string} userId - 用户唯一标识(长度 12~32 字符) * @param {import('./types/api').OrderFilter} filter - 筛选条件 * @returns {Promise<import>}</import> */async function fetchOrders(userId, filter) { ... }这类注释既能让编辑器提供精准补全,也能被 TypeDoc 工具一键生成在线 API 文档,无需额外维护两套内容。