导出原始 .ts 文件而不是 .d.ts 文件作为模块类型声明的后果
Posted
技术标签:
【中文标题】导出原始 .ts 文件而不是 .d.ts 文件作为模块类型声明的后果【英文标题】:Ramifications of exporting original .ts files instead of .d.ts files as module type declarations 【发布时间】:2019-06-21 06:46:44 【问题描述】:典型的 TypeScript 模块包含带有 TypeScript 源代码文件的 src
目录,运行 tsc -d --outDir dist
以将源代码编译为 dist
,并设置以下包元数据以让 Node.js 运行时和 TypeScript 编译器都了解模块正在导出:
"main": "dist/index.js",
"types": "dist/index.d.ts",
"files": ["dist"]
为了使调试更容易,通常需要软件包提供源映射和原始源代码。
使用最近引入的Project References 和编译器选项--declarationMap
,我觉得模块也应该提供声明映射文件,以允许IDE 从调用模块API 的地方直接跳转到实现,而不是生成的.d.ts
文件。
因此,一个模块将打包以下文件:
转译了运行时所需的.js
文件
调试所需的原始.ts
文件
TypeScript 编译器需要 .d.ts
中的声明
IDE 工具需要 .d.ts.map
中的声明映射
这个设置对我来说似乎过于复杂并引出了一个问题 - 如果我们摆脱 .d.ts
和 .d.ts.map
文件并提供原始 TypeScript 源代码会怎样?
"main": "dist/index.js",
"types": "src/index.ts",
"files": ["src", "dist"]
我想到的几个缺点:
根据我的模块编译项目时,TypeScript 编译器将有更多工作要做。它必须解析完整的.ts
源,而不是解析密集的.d.ts
文件。结果,构建可能会变慢。
对于 VSCode 等 IDE 也是如此:语言服务必须解析完整的 .ts
源,而不是加载最有可能针对快速解析进行优化的 .d.ts.map
文件。
.d.ts
和 .ts
文件之间也存在细微差别。前者仅导出声明(例如declare class Foo
),而后者导出定义(例如class Foo
)。我并不完全熟悉 TypeScript 如何处理依赖关系树中存在同一模块的多个实例的情况。它会以不同的方式处理声明的多个副本与定义的多个副本吗?
还有其他反对使用原始 .ts
文件作为类型声明的论据吗?
【问题讨论】:
【参考方案1】:通常需要软件包来提供源映射和原始 源代码也是。
这部分是正确的。源地图确实包含您的源代码。这就是为什么只要存在源映射,DevTools 就能够从缩小的 javascript 代码重新创建原始源。
我可以看到的一个缺点是您的包裹的大小。声明文件是轻量级的。大多数库可能都可以用一个小于 100 行代码的声明文件来描述。
然而,小的 API 表面并不意味着没有太多的源代码。你可以有一个包含数千个模块的项目,但它的公共 API 是一个单一的接口。使用*.d.ts
文件来描述它可以让您的消费者在他们的机器上节省大量空间。
【讨论】:
以上是关于导出原始 .ts 文件而不是 .d.ts 文件作为模块类型声明的后果的主要内容,如果未能解决你的问题,请参考以下文章
如果库的实现未与 TS 项目集成,如何使用 d.ts 文件导出的 const 类型?
使用复杂的 .d.ts 文件 (chrome-app.d.ts)
typeScript声明文件的一个注意点:不能使用导入导出语法
TypeScript 接口是不是应该在 *.d.ts 文件中定义