快速上手typescript-definition-style-guide:从零为原生ESM的npm包添加.d.ts类型定义完全教程
2026/8/28 8:36:41 网站建设 项目流程

快速上手typescript-definition-style-guide:从零为原生ESM的npm包添加.d.ts类型定义完全教程

【免费下载链接】typescript-definition-style-guideStyle guide for adding type definitions to my npm packages项目地址: https://gitcode.com/gh_mirrors/ty/typescript-definition-style-guide

你的npm包缺少 TypeScript 类型定义,用户在编辑器里只能看到一片any和缺失的自动补全?typescript-definition-style-guide是一个轻量、社区维护的风格指南,为原生 ESM 的 npm 包添加.d.ts类型定义文件提供了一份完整、可执行的清单。照着指南走,新手也能写出高质量类型定义,让用户获得精准的类型提示,让你的包瞬间更专业。🎉

为什么每个npm包都值得拥有.d.ts类型定义

  • 用户体验:用户安装你的包后,编辑器立刻提供参数补全、悬停说明和错误检查。
  • 专业形象:类型定义是现代化 npm 包的"门面",主流高质量项目几乎都随包自带.d.ts文件。
  • 成本远低于想象:一个类型定义文件常常只有十几行,却能给使用者带来巨大的体验提升。

一句话总结:好的 .d.ts = 一份免费的用户手册 + 一次自动的质量检查。

1分钟了解项目:这是一个什么样的指南

typescript-definition-style-guide 是一个纯文档项目,极其轻量:

文件作用
readme.md完整的风格指南正文(清单 + 命名规范 + 文档 + 测试)
licenseCC-BY-4.0 开源许可证
.editorconfig统一代码风格:tab 缩进、LF 换行、UTF-8 编码
.gitattributes换行符自动转换设置

完整指南就在readme.md中,没有任何框架和安装步骤,打开照着做即可。指南默认一个前提:你的包是原生 ESM 模块(即 package.json 中声明了"type": "module")。

准备工作:开始添加类型定义前的3个检查项

  1. 确认包是原生 ESM—— 指南全程基于此前提编写。
  2. 确认入口文件名—— 如果入口文件叫index.js,类型文件就命名为index.d.ts并放在包根目录,此时甚至不用在 package.json 里写types字段,TypeScript 会根据文件名自动推断。
  3. 确认第三方类型依赖—— 需要的类型要直接安装为依赖(例如把@types/node装为 dev dependency),不要在类型文件顶部写/// <reference types="node"/>三斜线引用。

类型定义清单速查:14条规则一次看全

指南的核心就是一张清单,以下是最关键条目的速查表:

#规则一句话说明
1代码风格tab 缩进 + 分号
2版本基准面向最新TypeScript 版本编写
3文档所有导出的属性/方法必须写文档
4测试类型定义必须被测试(见下文 tsd)
5Node 类型@types/node装为 dev 依赖,禁用三斜线引用
6第三方类型@types/*装为直接依赖,用 import 引入
7默认导出使用export default function foo(...)语法
8namespace不要使用
9字段名package.json 用"types",不用"typings"
10字段位置types放在官方字段之后、自定义字段之前(建议紧跟dependencies/devDependencies
11文件名入口为index.js时,类型文件为根目录的index.d.ts
12files 字段把类型定义文件加入 package.json 的files数组
13PR 标题统一为Add TypeScript definition
14社区贡献顺手帮忙评审他人的类型定义 PR

💡 指南还提醒:写类型前不妨扫一眼 DefinitelyTyped 的"常见错误"总结,能一次性避开绝大多数坑。

命名与写法:7条约定让类型定义质量立刻提升

这部分是指南的"灵魂",记住这几点就掌握了九成规范:

  • 类型不加命名空间前缀:参数类型就叫Options,不叫FooOptions(除非存在多个同名Options)。
  • 数组用简写number[]而非Array<number>;只读数组写readonly number[],而非ReadonlyArray<number>
  • unknown优于any:只要可能,就别偷懒用any
  • 不写缩写:命名用options而不是opts;接口名不以I开头。
  • 多个泛型参数要有可读名称Mapper<Element, NewElement>而不是Mapper<T, U>
  • 花括号内不留空格:命名导入、解构、对象字面量都写{foo}而非{ foo }
  • 拒绝宽松类型:不要用objectFunction,写具体签名如Record<string, number>(input: string) => boolean

一个容易忽视的细节:接收"字符串键值对象"时用Record<string, any>返回这类对象时用Record<string, unknown>—— 前者能让 TypeScript 在赋值时给你最大灵活度,后者会强制调用方先确认类型。

尽量使用只读值

如果一个值本就不该被修改,就不要让 TypeScript 允许它被修改:

type Point = { readonly x: number; readonly y: number; readonly children: readonly Point[]; };

返回值、配置选项对象这类"不该被改"的数据最适合加readonly,还可以配合Readonly工具类型把整个对象"冻结"。

显式导入类型、给导入起可读别名

不要依赖隐式全局类型(例如Electron.BrowserWindow),直接从来源导入。如果导入名太泛、容易混淆,就起个别名,比如把Writable导入为WritableStream,一眼就能看出它的用途。

TSDoc文档:类型定义的"门面"

指南要求所有导出的定义都写TSDoc格式的文档,文字可以直接从项目的 readme 里借用。一份标准函数文档长这样:

/** Add two numbers together. @param x - The first number to add. @param y - The second number to add. @returns The sum of `x` and `y`. */ export default function add(x: number, y: number, options?: Options): number;

细节不少,但全部为了可读性:

  • 句子首字母大写、以句号结尾;不要在行首加*,也不要硬换行;
  • @param后跟破折号,不要重复类型名;描述与参数名重复时直接省略(options参数甚至无需描述);
  • 默认值用@default标签说明;默认值是复杂描述时,写成Default: …的形式;
  • @returns,不是@return;返回值是voidPromise<void>时直接省略;
  • @example上方留一行空行,示例代码用三个反引号包裹;示例必须是完整可运行、且包含 import 语句的代码。

⚠️ 注意:环境声明不能有默认参数,所以带默认值的函数参数,要把默认值写进参数文档里。

用tsd测试类型定义:质量的最后一道防线

指南要求类型定义文件必须被测试,推荐工具是tsd—— 它在编译期"测试"类型:类型写错,测试直接失败。

标准流程:

  1. 新建一个名为index.test-d.ts的测试文件;
  2. expectType断言返回值类型符合预期;
  3. 合理时补充expectError()负向测试,验证"错误的用法确实会报错"。
import {expectType} from 'tsd'; import delay from './index.js'; expectType<Promise<void>>(delay(200));

两个值得记住的经验:

  • 测试返回 Promise 的函数时不要写await:直接断言Promise<…>的类型。否则await也会"放过"普通值,测试就形同虚设。
  • 需要传入字面量或只读常量时,记得用const 断言as const)。

快速上手:5步给你的包加上类型定义

  1. 打开 readme.md,把清单完整读一遍;
  2. 在包根目录创建index.d.ts(或与入口对应的文件),按上文命名规范写类型;
  3. 为每个导出的 API 补上 TSDoc 文档;
  4. 接入tsd,在index.test-d.ts中补上类型断言与负向测试;
  5. 把类型定义文件加入 package.json 的files字段,按需补types字段(命名为index.d.ts时可省略),最后逐条核对清单。

完成后,用户编辑器里会亮起你包的自动补全提示,价值立竿见影。✨

常见问题(FAQ)

问:我的包是 CommonJS,能用这份指南吗?指南以原生 ESM 包为前提,建议以 ESM 包直接使用;CJS 包可以借鉴其风格规范,但字段配置需按自己的实际情况调整。

问:装个@types/node再用三斜线引用行不行?不行。指南明确要求"直接依赖 + import"的方式,禁止三斜线引用,这样类型依赖才是透明、可管理的。

问:它和 DefinitelyTyped 有什么区别?DefinitelyTyped 集中存放第三方包的类型;而这份指南讲的是如何为自己随包发布的类型定义定标准——两者相辅相成,避坑时还可以参考 DefinitelyTyped 的常见错误总结。

【免费下载链接】typescript-definition-style-guideStyle guide for adding type definitions to my npm packages项目地址: https://gitcode.com/gh_mirrors/ty/typescript-definition-style-guide

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询