本页内容
TypeScript 支持
TypeScript 在 Deno 中是第一语言,就像 JavaScript 或 WebAssembly 一样。您无需安装除 Deno CLI 之外的任何其他东西即可运行或导入 TypeScript。Deno 凭借其内置的 TypeScript 编译器,无需额外配置即可将您的 TypeScript 代码编译为 JavaScript。Deno 还可以对您的 TypeScript 代码进行类型检查,而无需像 tsc
这样的独立类型检查工具。
类型检查 Jump to heading
TypeScript 的主要优点之一是它可以使您的代码类型安全,在开发而不是运行时捕获错误。TypeScript 是 JavaScript 的超集,这意味着语法上有效的 JavaScript 将成为 TypeScript,并附带关于“不安全”的警告。
Deno 允许您使用 deno check
子命令对代码进行类型检查(不执行)。
# Check the current directory/module
deno check
# Check a specific TypeScript file
deno check module.ts
# Include remote modules and npm packages in the check
deno check --all module.ts
# Check code snippets in JSDoc comments
deno check --doc module.ts
# 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 配合使用 Jump to heading
Deno 运行 JavaScript 和 TypeScript 代码。然而,在类型检查期间,Deno 默认只对 TypeScript 文件进行类型检查。如果您也想对 JavaScript 文件进行类型检查,您可以在文件顶部添加 // @ts-check
编译指示,或者将 compilerOptions.checkJs
添加到您的 deno.json
文件中。
// @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;
}
提供声明文件 Jump to heading
当从 TypeScript 代码导入未类型化的 JavaScript 模块时,您可能需要为 JavaScript 模块提供类型信息。如果 JavaScript 已用 TSDoc 注释进行标注,则不需要这样做。如果没有这些额外的类型信息(以 .d.ts
声明文件的形式),TypeScript 将假定从 JavaScript 模块导出的所有内容都是 any
类型。
tsc
会自动识别与 js
文件同级且具有相同基本名称的 d.ts
文件。Deno 不会这样做。 您必须在 .js
文件(源文件)或 .ts
文件(导入器)中明确指定 .d.ts
文件的位置。
在源文件中提供类型 Jump to heading
最好在 .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;
在导入器中提供类型 Jump to heading
如果您无法修改 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 模块提供类型 Jump to heading
通过 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 Worker 的类型检查 Jump to heading
默认情况下,Deno 对 TypeScript 模块进行类型检查,就好像它们在 Deno 运行时的主线程中运行一样。然而,Deno 还支持浏览器类型检查、Web Worker 类型检查以及结合浏览器和 Deno 的环境(例如在 Deno 中使用 SSR(服务器端渲染))的类型检查。
这些环境具有不同的全局对象和可用 API。Deno 以库文件的形式为这些环境提供类型定义。这些库文件由 TypeScript 编译器使用,以提供这些环境中可用的全局对象和 API 的类型信息。
可以使用 deno.json
配置文件中的 compilerOptions.lib
选项,或者通过 TypeScript 文件中的 /// <reference lib="..." />
注释来更改加载的库文件。建议在 deno.json
配置文件中使用 compilerOptions.lib
选项来指定要使用的库文件。
要为浏览器环境启用类型检查,您可以在 deno.json
配置文件中的 compilerOptions.lib
选项中指定 dom
库文件。
{
"compilerOptions": {
"lib": ["dom"]
}
}
这将为浏览器环境启用类型检查,提供对 document
等全局对象的类型信息。然而,这将禁用对 Deno.readFile
等 Deno 特有 API 的类型信息。
要为结合浏览器和 Deno 环境(例如在 Deno 中使用 SSR)启用类型检查,您可以在 deno.json
配置文件中的 compilerOptions.lib
选项中同时指定 dom
和 deno.ns
(Deno 命名空间)库文件。
{
"compilerOptions": {
"lib": ["dom", "deno.ns"]
}
}
这将为浏览器和 Deno 环境启用类型检查,提供对 document
等全局对象以及 Deno.readFile
等 Deno 特有 API 的类型信息。
要在 Deno 中为 Web Worker 环境(即通过 new Worker
运行的代码)启用类型检查,您可以在 deno.json
中的 compilerOptions.lib
选项中指定 deno.worker
库文件。
{
"compilerOptions": {
"lib": ["deno.worker"]
}
}
要在 TypeScript 文件中指定要使用的库文件,您可以使用 /// <reference lib="..." />
注释。
/// <reference no-default-lib="true" />
/// <reference lib="dom" />
增强全局类型 Jump to heading
Deno 支持 TypeScript 中的环境或全局类型。这在为全局对象提供 polyfill 或用额外属性增强全局作用域时很有用。您应尽可能避免使用环境或全局类型,因为它们可能导致命名冲突并使您的代码更难理解。在发布到 JSR 时,它们也不受支持。
要在 Deno 中使用环境或全局类型,您可以使用 declare global
语法,或加载一个增强全局作用域的 .d.ts
文件。
使用 declare global 增强全局作用域 Jump to heading
您可以在项目中导入的任何 TypeScript 文件中使用 declare global
语法,以使用额外属性增强全局作用域。例如:
declare global {
interface Window {
polyfilledAPI(): string;
}
}
当类型定义被导入时,这使得 polyfilledAPI
函数在全局范围内可用。
使用 .d.ts 文件增强全局作用域 Jump to heading
您也可以使用 .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
函数增强全局作用域。