Deno 中 TypeScript 的常见问题解答
我可以使用未为 Deno 编写的 TypeScript 吗?
也许。我们担心,这是最好的答案。由于很多原因,Deno 选择使用完全限定的模块说明符。部分原因是它将 TypeScript 视为一等公民语言。此外,Deno 使用显式模块解析,没有 *魔法*。这实际上与浏览器本身的工作方式相同,尽管它们显然不支持 TypeScript。如果 TypeScript 模块使用的导入没有考虑到这些设计决策,它们可能无法在 Deno 下运行。
此外,在 Deno 的最新版本(从 1.5 开始),我们开始使用 Rust 库在某些情况下对 TypeScript 进行转换为 JavaScript。因此,在 TypeScript 中存在某些情况需要类型信息,因此这些情况在 Deno 下不受支持。如果您使用 tsc
作为独立工具,则要使用的设置是 "isolatedModules"
,并将其设置为 true
以帮助确保您的代码可以由 Deno 正确处理。
解决扩展问题和缺乏 Node.js 非标准解析逻辑的一种方法是使用 导入映射,它允许您指定“包”的裸说明符,然后 Deno 可以解析和加载这些说明符。
Deno 支持哪些版本的 TypeScript?
Deno 是使用特定版本的 TypeScript 构建的。要找出是什么版本,请在命令行中输入以下内容
> deno --version
将打印 TypeScript 版本(以及 Deno 和 v8 的版本)。Deno 试图跟上 TypeScript 的通用版本发布,并在 Deno 的下一个补丁或次要版本中提供它们。
Deno 使用的 TypeScript 版本存在重大更改,为什么您破坏了我的程序?
我们不认为 TypeScript 版本中的行为更改或重大更改是 Deno 的重大更改。TypeScript 是一种通常成熟的语言,TypeScript 中的重大更改几乎总是“好事”,使代码更加健壮,我们最好让我们的代码保持健壮。如果 TypeScript 版本中存在阻塞更改,并且在问题解决之前不适合使用旧版本的 Deno,那么您应该能够使用 --no-check
完全跳过类型检查。
此外,您可以使用 @ts-ignore
来 *忽略* 您控制的代码中的特定错误。您还可以使用 导入映射 替换整个依赖项,用于依赖项的依赖项未维护或存在您想绕过的重大更改的情况,同时等待更新。
如何在 Deno 和浏览器中编写代码,同时仍然进行类型检查?
您可以通过使用包含 --config
选项的配置文件,并在该文件中的 "compilerOptions"
中调整 "lib"
选项来实现。有关更多信息,请参阅 针对 Deno 和浏览器。
为什么您强迫我使用隔离模块,为什么我不能在 Deno 中使用 const 枚举,为什么我需要使用 export type?
从 Deno 1.5 开始,我们默认将 isolatedModules 设置为 true
,在 Deno 1.6 中,我们删除了通过配置文件将其设置回 false
的选项。isolatedModules 选项强制 TypeScript 编译器检查和发出 TypeScript,就好像每个模块都是独立存在的。TypeScript 目前在语言中有一些 类型导向的发出。虽然不允许类型导向的发出进入语言是 TypeScript 的设计目标,但它还是发生了。这意味着 TypeScript 编译器需要理解代码中的可擦除类型才能确定要发出什么,当您试图在 JavaScript 之上构建一个完全可擦除的类型系统时,这就会成为一个问题。
当人们开始在没有 tsc
的情况下转译 TypeScript 时,这些类型导向的发出就成了一个问题,因为像 Babel 这样的工具只是试图擦除类型,而不需要理解类型来指导发出。
因此,我们没有试图让每个用户都理解我们何时以及如何支持类型导向的发出,而是决定通过强制 isolatedModules 选项为 true
来禁用它们的使用。这意味着即使我们使用 TypeScript 编译器来发出代码,它也会遵循与基于 Rust 的发出器相同的“规则”。
这意味着某些语言特性不支持。这些特性包括
- 类型的重新导出是模棱两可的,需要知道源模块是导出运行时代码还是仅仅类型信息。因此,建议您使用 `import type` 和 `export type` 进行仅类型导入和导出。这将有助于确保在代码发出时,所有类型都被擦除。
- 不支持 `const enum`。`const enum` 需要类型信息来指导发出,因为 `const enum` 被写成硬编码值。特别是当 `const enum` 被导出时,它们只是类型系统中的构造。
- 不支持 `export =` 和 `import =`。它们是旧的 TypeScript 语法,我们不支持。
- 仅支持 `declare namespace`。运行时 `namespace` 是旧的 TypeScript 语法,不支持。
为什么不支持语言服务插件或转换器插件?
虽然 `tsc` 支持语言服务插件,但 Deno 不支持。Deno 不总是使用内置的 TypeScript 编译器来完成它所做的事情,并且添加对语言服务插件的支持的复杂性不可行。TypeScript 不支持发射器插件,但有一些社区项目将发射器插件“黑客”到 TypeScript 中。首先,我们不想支持 TypeScript 不支持的东西,而且我们并不总是使用 TypeScript 编译器来进行发射,这意味着我们需要确保我们在所有模式下都支持它,而另一个发射器是用 Rust 编写的,这意味着任何用于 TypeScript 的发射器插件都将无法用于 Rust 发射器。
如何在 IDE 中将 Deno 代码与非 Deno 代码结合起来?
Deno 语言服务器支持对每个资源进行配置,以启用或禁用 Deno。这还需要客户端 IDE 支持此功能。对于 Visual Studio Code,官方的 Deno 扩展 支持 vscode 的 多根工作区 概念。这意味着您只需将文件夹添加到工作区,并在每个文件夹上根据需要设置 deno.enable
设置。
对于其他 IDE,客户端扩展需要支持类似的 IDE 概念。