跳至主要内容
在本页

TypeScript 支持

TypeScript 是 Deno 中的一流语言,就像 JavaScript 或 WebAssembly 一样。你可以运行或导入 TypeScript,而无需安装除 Deno CLI 之外的任何东西。借助其内置的 TypeScript 编译器,Deno 会将你的 TypeScript 代码编译成 JavaScript,而无需任何额外的配置。Deno 还可以对你的 TypeScript 代码进行类型检查,而无需使用单独的类型检查工具,例如 `tsc`。

类型检查 跳转到标题

TypeScript 的主要优势之一是它可以使你的代码类型安全,在开发过程中而不是运行时捕获错误。TypeScript 是 JavaScript 的超集,这意味着语法有效的 JavaScript 成为 TypeScript,并带有关于“不安全”的警告。

注意

**Deno 默认以 `strict mode` 对 TypeScript 进行类型检查**,TypeScript 核心团队建议严格模式作为明智的默认值

Deno 允许你使用 `deno check` 子命令对你的代码进行类型检查(而不执行它)。

deno check module.ts
# or also type check remote modules and npm packages
deno check --all module.ts
# code snippets written in JSDoc can also be type checked
deno check --doc module.ts
# or type check code snippets in markdown files
deno check --doc-only markdown.md

注意

类型检查可能需要大量时间,尤其是在你正在进行大量更改的代码库上。Deno 优化了类型检查,但它仍然需要付出代价。因此,**默认情况下,TypeScript 模块在执行之前不会进行类型检查**。

当使用 `deno run` 命令时,Deno 会跳过类型检查并直接运行代码。为了在执行发生之前对模块进行类型检查,你可以使用 `deno run` 的 `--check` 标志。

deno run --check module.ts
# or also type check remote modules and npm packages
deno run --check=all module.ts

当 Deno 在使用此标志时遇到类型错误时,进程将在执行代码之前退出。

为了避免这种情况,你需要:

  • 解决问题
  • 使用 `// @ts-ignore` 或 `// @ts-expect-error` 注释来忽略错误
  • 或完全跳过类型检查。

在测试代码时,类型检查默认启用。如果需要,你可以使用 `--no-check` 标志跳过类型检查。

deno test --no-check

与 JavaScript 结合使用 跳转到标题

Deno 运行 JavaScript 和 TypeScript 代码。在类型检查期间,Deno 默认只检查 TypeScript 文件。如果你还想检查 JavaScript 文件,你可以 either 在文件顶部添加 `// @ts-check` 注释,或者在你的 `deno.json` 文件中添加 `compilerOptions.checkJs`。

main.js
// @ts-check

let x = "hello";
x = 42; // Type 'number' is not assignable to type 'string'.
deno.json
{
  "compilerOptions": {
    "checkJs": true
  }
}

在 JavaScript 文件中,你不能使用 TypeScript 语法,例如类型注释或导入类型。但是,你可以使用 TSDoc 注释为 TypeScript 编译器提供类型信息。

main.js
// @ts-check

/**
 * @param a {number}
 * @param b {number}
 * @returns {number}
 */
function add(a, b) {
  return a + b;
}

提供声明文件 跳转到标题

从 TypeScript 代码导入未类型化的 JavaScript 模块时,你可能需要为 JavaScript 模块提供类型信息。如果 JavaScript 使用 TSDoc 注释进行注释,则不需要这样做。如果没有这种额外的类型信息(以 `.d.ts` 声明文件的形式),TypeScript 将假设从 JavaScript 模块导出的所有内容都为 `any` 类型。

`tsc` 会自动拾取与 `js` 文件同级且具有相同基名的 `d.ts` 文件。**Deno 不会这样做。**你必须在 `.js` 文件(源代码)或 `.ts` 文件(导入器)中明确指定在哪里可以找到 `.d.ts` 文件。

在源

建议在.js文件中指定.d.ts文件,这样可以更容易地从多个 TypeScript 模块中使用 JavaScript 模块:你无需在导入 JavaScript 模块的每个 TypeScript 模块中都指定.d.ts文件。

add.js
// @ts-self-types="./add.d.ts"

export function add(a, b) {
  return a + b;
}
add.d.ts
export function add(a: number, b: number): number;

在导入者中提供类型 跳转至标题

如果你无法修改 JavaScript 源代码,可以在导入 JavaScript 模块的 TypeScript 模块中指定.d.ts文件。

main.ts
// @ts-types="./add.d.ts"
import { add } from "./add.js";

这对不提供类型信息的 NPM 包也很有用。

main.ts
// @ts-types="npm:@types/lodash"
import * as _ from "npm:lodash";

为 HTTP 模块提供类型 跳转至标题

通过 HTTP 托管 JavaScript 模块的服务器也可以在 HTTP 标头中为这些模块提供类型信息。Deno 在对模块进行类型检查时会使用这些信息。

HTTP/1.1 200 OK
Content-Type: application/javascript; charset=UTF-8
Content-Length: 648
X-TypeScript-Types: ./add.d.ts

X-TypeScript-Types 标头指定了提供 JavaScript 模块类型信息的.d.ts文件的位置。它的解析方式与Location标头类似,相对于 JavaScript 模块的 URL 进行解析。

针对浏览器和 Web 工作者的类型检查 跳转至标题

默认情况下,Deno 对 TypeScript 模块进行类型检查,就像它们在 Deno 运行时的主线程中运行一样。但是,Deno 也支持针对浏览器的类型检查、针对 Web 工作者的类型检查以及针对组合浏览器-Deno 环境的类型检查,例如在使用 Deno 进行 SSR(服务器端渲染)时。

这些环境有不同的全局对象和可用的 API。Deno 以库文件形式为这些环境提供类型定义。TypeScript 编译器使用这些库文件为这些环境中可用的全局对象和 API 提供类型信息。

可以使用deno.json配置文件中的compilerOptions.lib选项,或通过 TypeScript 文件中的/// <reference lib="..." />注释来更改加载的库文件。建议在deno.json配置文件中使用compilerOptions.lib选项来指定要使用的库文件。

要启用针对浏览器环境的类型检查,可以在deno.json配置文件中将dom库文件指定到compilerOptions.lib选项中。

deno.json
{
  "compilerOptions": {
    "lib": ["dom"]
  }
}

这将启用针对浏览器环境的类型检查,为document等全局对象提供类型信息。但这会禁用针对 Deno 特定 API(如Deno.readFile)的类型信息。

要启用针对组合浏览器和 Deno 环境的类型检查(例如,使用 Deno 进行 SSR),可以在deno.json配置文件中将domdeno.ns(Deno 命名空间)库文件都指定到compilerOptions.lib选项中。

deno.json
{
  "compilerOptions": {
    "lib": ["dom", "deno.ns"]
  }
}

这将启用针对浏览器和 Deno 环境的类型检查,为document等全局对象以及Deno.readFile等 Deno 特定 API 提供类型信息。

要启用针对Deno 中 Web 工作者环境的类型检查(即使用new Worker运行的代码),可以在deno.json中的compilerOptions.lib选项中指定deno.worker库文件。

deno.json
{
  "compilerOptions": {
    "lib": ["deno.worker"]
  }
}

要指定 TypeScript 文件中要使用的库文件,可以使用/// <reference lib="..." />注释。

/// <reference no-default-lib="true" />
/// <reference lib="dom" />

扩展全局类型 跳转至标题

Deno 支持 TypeScript 中的环境或全局类型。当对全局对象进行填充或用附加属性扩展全局范围时,这很有用。应尽量避免使用环境或全局类型,因为它们会导致命名冲突并使代码更难推理。在发布到 JSR 时也不支持它们。

要在 Deno 中使用环境或全局类型,可以使用declare global语法,或加载扩展全局范围的.d.ts文件。

使用 declare global 来扩展全局范围 跳转至标题

可以在项目中导入的任何 TypeScript 文件中使用declare global语法来扩展全局范围,为其添加附加属性。例如

declare global {
  interface Window {
    polyfilledAPI(): string;
  }
}

导入类型定义后,polyfilledAPI函数将在全局范围内可用。

使用 .d.ts 文件来扩展全局范围 跳转至标题

也可以使用.d.ts文件来扩展全局范围。例如,可以创建一个global.d.ts文件,内容如下

interface Window {
  polyfilledAPI(): string;
}

然后,可以在 TypeScript 中使用/// <reference types="./global.d.ts" />加载此.d.ts文件。这将用polyfilledAPI函数扩展全局范围。

或者,可以在deno.json配置文件的compilerOptions.types数组中指定.d.ts文件。

{
  "compilerOptions": {
    "types": ["./global.d.ts"]
  }
}

这也会用polyfilledAPI函数扩展全局范围。