在本页
TypeScript 支持
TypeScript 是 Deno 中的一流语言,就像 JavaScript 或 WebAssembly 一样。你可以运行或导入 TypeScript,而无需安装除 Deno CLI 之外的任何东西。借助其内置的 TypeScript 编译器,Deno 会将你的 TypeScript 代码编译成 JavaScript,而无需任何额外的配置。Deno 还可以对你的 TypeScript 代码进行类型检查,而无需使用单独的类型检查工具,例如 `tsc`。
类型检查 跳转到标题
TypeScript 的主要优势之一是它可以使你的代码类型安全,在开发过程中而不是运行时捕获错误。TypeScript 是 JavaScript 的超集,这意味着语法有效的 JavaScript 成为 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`。
// @ts-check
let x = "hello";
x = 42; // Type 'number' is not assignable to type 'string'.
{
"compilerOptions": {
"checkJs": true
}
}
在 JavaScript 文件中,你不能使用 TypeScript 语法,例如类型注释或导入类型。但是,你可以使用 TSDoc 注释为 TypeScript 编译器提供类型信息。
// @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
文件。
// @ts-self-types="./add.d.ts"
export function add(a, b) {
return a + b;
}
export function add(a: number, b: number): number;
在导入者中提供类型 跳转至标题
如果你无法修改 JavaScript 源代码,可以在导入 JavaScript 模块的 TypeScript 模块中指定.d.ts
文件。
// @ts-types="./add.d.ts"
import { add } from "./add.js";
这对不提供类型信息的 NPM 包也很有用。
// @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
选项中。
{
"compilerOptions": {
"lib": ["dom"]
}
}
这将启用针对浏览器环境的类型检查,为document
等全局对象提供类型信息。但这会禁用针对 Deno 特定 API(如Deno.readFile
)的类型信息。
要启用针对组合浏览器和 Deno 环境的类型检查(例如,使用 Deno 进行 SSR),可以在deno.json
配置文件中将dom
和deno.ns
(Deno 命名空间)库文件都指定到compilerOptions.lib
选项中。
{
"compilerOptions": {
"lib": ["dom", "deno.ns"]
}
}
这将启用针对浏览器和 Deno 环境的类型检查,为document
等全局对象以及Deno.readFile
等 Deno 特定 API 提供类型信息。
要启用针对Deno 中 Web 工作者环境的类型检查(即使用new Worker
运行的代码),可以在deno.json
中的compilerOptions.lib
选项中指定deno.worker
库文件。
{
"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
函数扩展全局范围。