在 Deno 中配置 TypeScript
TypeScript 带有许多不同的配置选项,但 Deno 努力使 TypeScript 与 Deno 的使用变得容易。许多不同的选项会阻碍这一目标。为了简化操作,Deno 配置 TypeScript 使其“正常工作”,无需额外配置。
也就是说,Deno 支持使用 TypeScript 配置文件。要在 Deno 中使用 TypeScript 配置文件,您可以在命令行中提供路径,或使用默认路径。例如
> deno run --config ./deno.json main.ts
⚠️ 但是请注意,如果您正在创建需要配置文件的库,那么如果您将模块作为 TypeScript 分发,所有使用您模块的用户也将需要该配置文件。此外,您在配置文件中进行的设置可能会导致其他 TypeScript 模块不兼容。老实说,最好使用 Deno 默认设置,并认真考虑是否使用配置文件。
⚠️ Deno v1.14 开始支持更通用的配置文件,不再局限于指定 TypeScript 编译器设置。使用
tsconfig.json
作为文件名仍然有效,但我们建议使用deno.json
或deno.jsonc
,因为计划在即将发布的版本中自动查找此文件。
Deno 如何使用配置文件
Deno 不会像 tsc
那样处理 TypeScript 配置文件,因为 TypeScript 配置文件中有很多部分在 Deno 上下文中毫无意义,或者如果应用它们会导致 Deno 无法正常运行。
Deno 只会查看配置文件中的 compilerOptions
部分,即使这样,它也只考虑某些编译器选项,其余选项将被忽略。
以下是可以更改的编译器选项、它们在 Deno 中的默认值以及有关该选项的其他说明
选项 | 默认值 | 说明 |
---|---|---|
allowJs | true | 这几乎不需要更改 |
allowUnreachableCode | false | |
allowUnusedLabels | false | |
checkJs | false | 如果为 true ,则会导致 TypeScript 对 JavaScript 进行类型检查 |
jsx | "react" | |
jsxFactory | "React.createElement" | |
jsxFragmentFactory | "React.Fragment" | |
keyofStringsOnly | false | |
lib | [ "deno.window" ] | 此选项的默认值根据 Deno 中的其他设置而有所不同。如果提供了此选项,它将覆盖默认值。有关更多信息,请参见下文。 |
noErrorTruncation | false | |
noFallthroughCasesInSwitch | false | |
noImplicitAny | true | |
noImplicitReturns | false | |
noImplicitThis | true | |
noImplicitUseStrict | true | |
noStrictGenericChecks | false | |
noUnusedLocals | false | |
noUnusedParameters | false | |
noUncheckedIndexedAccess | false | |
reactNamespace | React | |
strict | true | |
strictBindCallApply | true | |
strictFunctionTypes | true | |
strictPropertyInitialization | true | |
strictNullChecks | true | |
suppressExcessPropertyErrors | false | |
suppressImplicitAnyIndexErrors | false | |
useUnknownInCatchVariables | false |
有关编译器选项的完整列表及其对 TypeScript 的影响,请参阅 TypeScript 手册。
隐式 tsconfig.json 的样子
无法让tsc
像Deno一样运行。同样,也很难让TypeScript语言服务像Deno一样运行。这就是我们直接在Deno中构建语言服务的原因。话虽如此,理解其中的含义还是很有用的。
如果你要为Deno编写一个tsconfig.json
,它看起来会像这样
{
"compilerOptions": {
"allowJs": true,
"esModuleInterop": true,
"experimentalDecorators": false,
"inlineSourceMap": true,
"isolatedModules": true,
"jsx": "react",
"lib": ["deno.window"],
"module": "esnext",
"moduleDetection": "force",
"strict": true,
"target": "esnext",
"useDefineForClassFields": true
}
}
你不能直接将这段代码复制粘贴到配置文件中并使其生效,特别是因为Deno内置了自定义的类型库,这些库是提供给TypeScript编译器的。可以通过在命令行中运行deno types
并将输出管道到一个文件,并将该文件包含在程序文件中,删除"lib"
选项,并将"noLib"
选项设置为true
来模拟这种行为。
如果你使用--unstable
标志,Deno会将"lib"
选项更改为[ "deno.window", "deno.unstable" ]
。如果你尝试加载一个worker,它将使用"deno.worker"
而不是"deno.window"
进行类型检查。有关此方面的更多信息,请参阅类型检查Web Workers。
使用"lib"属性
Deno内置了一些其他平台(如tsc
)中不存在的库。这使得Deno能够正确地检查为Deno编写的代码。但在某些情况下,这种自动行为会导致挑战,例如编写旨在也在浏览器中运行的代码。在这些情况下,可以使用compilerOptions
中的"lib"
属性来修改Deno在类型检查代码时的行为。
对用户来说,内置库中最重要的是
"deno.ns"
- 这包括所有自定义的Deno
全局命名空间API以及Deno对import.meta
的扩展。这通常不会与其他库或全局类型发生冲突。"deno.unstable"
- 这包括添加的不稳定Deno
全局命名空间API。"deno.window"
- 这是检查Deno主运行时脚本时使用的“默认”库。它包括"deno.ns"
以及内置于Deno的扩展的其他类型库。该库将与"dom"
和"dom.iterable"
等标准TypeScript库发生冲突。"deno.worker"
- 这是检查Deno Web Worker脚本时使用的库。有关Web Worker的更多信息,请查看类型检查Web Workers。"dom.asynciterable"
- TypeScript 目前不包含 Deno(以及多个浏览器)实现的 DOM 异步可迭代对象,因此我们自己实现了它,直到它在 TypeScript 中可用。
这些是 Deno 不使用的常用库,但在编写旨在在其他运行时中也工作的代码时很有用。
"dom"
- 与 TypeScript 一起提供的主要的浏览器全局库。类型定义在许多方面与"deno.window"
冲突,因此如果使用"dom"
,则考虑仅使用"deno.ns"
来公开 Deno 特定的 API。"dom.iterable"
- 浏览器全局库的可迭代扩展。"scripthost"
- Microsoft Windows 脚本宿主库。"webworker"
- 浏览器中 Web 工作者的主要库。与"dom"
一样,这将与"deno.window"
或"deno.worker"
冲突,因此考虑仅使用"deno.ns"
来公开 Deno 特定的 API。"webworker.importscripts"
- 公开 Web 工作者中importScripts()
API 的库。"webworker.iterable"
- 在 Web 工作者中向对象添加可迭代对象的库。现代浏览器支持此功能。
针对 Deno 和浏览器
一个常见的用例是编写在 Deno 和浏览器中都能工作的代码:使用条件检查来确定代码执行的环境,然后再使用任何仅限于其中一个环境的 API。如果是这种情况,compilerOptions
的常见配置如下所示
{
"compilerOptions": {
"target": "esnext",
"lib": ["dom", "dom.iterable", "dom.asynciterable", "deno.ns"]
}
}
这应该允许 Deno 正确地对大多数代码进行类型检查。
如果您希望使用 --unstable
标志在 Deno 中运行代码,那么您还需要将该库添加到混合中
{
"compilerOptions": {
"target": "esnext",
"lib": [
"dom",
"dom.iterable",
"dom.asynciterable",
"deno.ns",
"deno.unstable"
]
}
}
通常,当您在 TypeScript 中使用 "lib"
选项时,您还需要包含一个 "es" 库。在 "deno.ns"
和 "deno.unstable"
的情况下,它们在您引入它们时会自动包含 "esnext"
。
这样做最大的 "危险" 是类型检查明显更宽松,并且无法验证您是否在代码中进行了充分有效的特性检测,这可能会导致原本微不足道的错误变成运行时错误。
使用 "types" 属性
在 "compilerOptions"
中的 "types"
属性可用于指定在类型检查程序时要包含的任意类型定义。有关此内容的更多信息,请参见 使用环境或全局类型。