Typescript 不会复制 d.ts 文件来构建

Posted

技术标签:

【中文标题】Typescript 不会复制 d.ts 文件来构建【英文标题】:Typescript does not copy d.ts files to build 【发布时间】:2019-09-24 20:31:00 【问题描述】:

所以也许我很困惑,但我认为如果我将 declaration:true 添加到我的 tsconfig.json 中,我可以让它 tsc 复制我的 *.d.ts 文件,以及转译的代码和它的 d.ts 文件?

EG:

- src
 - lib
   - types.d.ts
   - foo.ts

我希望 tsc 的结果类似于:

- build
 - lib
   - types.d.ts
   - foo.js
   - foo.d.ts

但是,我似乎无法将 types.d.ts 复制到我的构建目录中。

打字稿不提供任何机制来复制.d.ts 文件吗?还是我只是在某个地方配置错误? (此时我已经尝试了很多不同的配置;似乎没有任何效果)

【问题讨论】:

似乎declaration:true 仅指从.ts 文件创建声明...仍然看起来非常奇怪,没有某种方法可以轻松地将我的环境 .d.ts 文件复制到构建中 【参考方案1】:

你是对的 - declaration:true 意味着只有每个给定的 .ts 文件 tsc 生成一个相应的 .d.ts 输出文件并将其复制到 build 目录(除了 .js.map如果适用)。所以tsc 不会将你自定义的types.d.ts 文件复制到输出目录。

基本上.d.ts 文件被视为编译器进行类型检查的不可触摸输入。它们不用于任何输出生成,这也意味着它们不会被复制到build。你可以阅读更多关于维护者立场的here:

您使用的 .d.ts 文件是构建系统的输入,而不是输出。从 .d.ts 使用某些类型是完全合理的,但您的输出不使用这些类型,因此没有理由将输入 .d.ts 与您的构建结果一起分发。 [...] 听起来您需要在构建工具中执行构建后步骤,以便将相关的 .d.ts 文件复制到您需要的任何位置。

.d.ts 文件被认为是“引用”,编译器不会触及它们、不会移动它们或重新创建它们。考虑 .d.ts 文件的一种简单方法是它们与您的 .js 文件一起使用。如果要复制 .js 文件,则应复制匹配的 .d.ts。

解决方案 #1:通过手动构建步骤复制 d.ts 文件

一种可能的解决方案是在构建步骤中手动复制所有需要的.d.ts 文件,例如types.d.ts。具体工具取决于您的项目和构建类型、操作系统等。此工具在将文件复制到build 时应保留src 下的目录结构,以便import 类型引用仍然有效。仅举几例:cp --parents(shell)、rsyncrobocopy 或独立于平台的 npm 包,如 copyfiles:

"scripts": 
  "copy-dts": "copyfiles -u 1 \"src/**/*.d.ts\" build"

解决方案 #2:将 d.ts 文件改写为 .ts 扩展名

将您的.d.ts 文件改写为.ts 扩展名(或将类型重新集成到现有的.ts 文件中),因此tsc 负责在输出中发出声明。轻微的缺点:您没有编译器强制类型和实现代码之间的分离(d.ts 文件不允许包含代码)。最大的优势是,您不需要额外的构建步骤。

在我看来,后者是生成公共 API 的最简单方法,例如对于您的 npm 包,而 .d.ts 文件可以作为内部使用和共享类型声明的候选者。

希望,这会有所帮助。

【讨论】:

我的方法只是将我的全局类型写入.ts 文件中...您认为这样做有什么缺点吗? @NSjonas 更新了我的答案,还提到了您使用 .ts 文件获取类型的方法。 值得一提 - 解决方案 #2 也会导致编译器创建一个空的 js 文件...

以上是关于Typescript 不会复制 d.ts 文件来构建的主要内容,如果未能解决你的问题,请参考以下文章

typescript .d.ts 文件的搜索路径

获取TypeScript的声明文件.d.ts

Typescript 生成带有 `#private;` 字段的声明 d.ts 文件

TypeScript 接口是不是应该在 *.d.ts 文件中定义

如何编写 Typescript 声明文件

TypeScript 和 jQuery 等库(带有 .d.ts 文件)