应启用tsconfig.json的declaration:true以生成.d.ts供文档工具解析,jsdoc需与ts类型对齐,优先依赖类型系统而非冗余注释,用typedoc替代apidoc可准确处理泛型等复杂类型。

能直接用 TypeScript 的类型系统驱动文档生成,就别手写 JSDoc 模板。关键不是“有没有注释”,而是“注释是否被编译器识别、是否与类型签名一致”。
tsconfig.json 必须启用 declaration 和 allowJs(如果混用 JS)
很多项目跑 tsc 不报错,但 typedoc 或 tsc --emitDeclarationOnly 输出为空,根源常在这里。TypeScript 默认不生成 .d.ts,而多数文档工具(如 TypeDoc、Fumadocs)依赖声明文件或类型节点树。
-
"declaration": true是开关,没它就没有类型输出 -
"allowJs": true仅在你有.js文件且含 JSDoc 时需要;否则可省略 -
"emitDeclarationOnly": true能跳过 JS 编译,加快 CI 中的文档构建 -
"skipLibCheck": true避免第三方类型定义拖慢解析,不影响你的源码文档生成
JSDoc 注释必须和类型签名对齐,否则 TypeDoc 会忽略或误读
TypeDoc(以及 Fumadocs、apidoc 的 TS 插件)本质是解析 AST 中的类型节点 + JSDoc 节点。如果你写:
/**
* @param {string} name - 用户名
* @returns {number}
*/
function getId(name) {
return name.length;
}
——这在 JS 环境下能工作,但在 TS 里,getId 实际签名是 (name: any) => number,TypeDoc 会优先信任类型系统,把 @param 当作冗余信息丢弃。
- 正确做法:删掉
@param,直接靠 TS 类型 +@remarks补充语义 - 保留
@example、@deprecated、@internal这类非类型类标签,它们不会和类型冲突 - 避免
@type显式标注变量类型(如/** @type {User[]} */),TS 已能推导时反而干扰解析
用 typedoc 替代 apidoc + jsdoc 组合,减少中间层失真
apidoc 基于正则扫描注释字符串,对泛型、联合类型、条件类型支持极弱;而 TypeDoc 直接消费 TypeScript 编译器的 Program 对象,能准确还原 Promise<result>></result> 这种嵌套结构。
- 安装:
npm install -D typedoc typescript - 最小配置
typedoc.json:{ "entryPoints": ["src/index.ts"], "out": "docs", "tsconfig": "tsconfig.json", "excludePrivate": true, "excludeProtected": true } - CI 中加一行:
npx typedoc --out docs --no-github-pages,避免网络请求失败中断流程 - 若需 Markdown 输出(比如集成进 Docusaurus),额外装插件:
npm install -D typedoc-plugin-markdown,再加--plugin typedoc-plugin-markdown
不要指望 JSDoc 自动生成完整类型文档
一个 interface User { id: string; name?: string; },即使没写任何 JSDoc,TypeDoc 也能生成字段列表和可选标记。但 @default、@remarks、@example 这些才是人工不可替代的部分——它们解释“为什么这么设计”,而不是“它是什么”。
-
@default在interface字段上无效,只对函数参数或对象字面量属性起作用 -
@internal和/** @internal */注释效果不同:前者是 TSDoc 标准,后者是旧式 JSDoc,TypeDoc 只认前者 - 复杂类型(如
Record<string array number>></string>)建议拆成命名type,否则文档里会显示一长串无法折叠的内联类型
真正难的不是生成文档,是让团队在改类型时顺手更新 @remarks 和 @example。这类内容无法被编译器校验,一旦滞后,文档比没有还危险。











