本页内容
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 不支持发出器插件,但有一些社区项目将发出器插件hack到 TypeScript 中。首先,我们不想支持 TypeScript 不支持的东西,而且我们并不总是使用 TypeScript 编译器来发出代码,这意味着我们需要确保我们在所有模式下都支持它,而另一个发出器是用 Rust 编写的,这意味着任何针对 TypeScript 的发出器插件都将无法用于 Rust 发出器。
如何在 IDE 中将 Deno 代码与非 Deno 代码结合起来? 跳转到标题
Deno 语言服务器支持对每个资源进行配置,以启用或禁用 Deno。这也要求客户端 IDE 支持此功能。对于 Visual Studio Code,官方的 Deno 扩展 支持 vscode 的 多根工作区 概念。这意味着您只需要将文件夹添加到工作区,并在每个文件夹上根据需要设置 deno.enable
设置。
对于其他 IDE,客户端扩展需要支持类似的 IDE 概念。