使用 Deno 编译时如何使用 lib.dom.d.ts 中的类型?

TPR*_*eal 4 dom typescript deno

我使用 Deno 编译一些 TypeScript,然后将其作为网页的一部分提供,以便它在浏览器端运行。我正在尝试在客户端使用 canvas 元素,为此我需要类似CanvasRenderingContext2Dor 的类型CanvasGradient,它们在lib.dom.d.ts中定义,但它们不可用:Deno 编译给出类似 的错误TS2304 [ERROR]: Cannot find name 'CanvasRenderingContext2D'.。(另一方面,类型Path2D(在同一文件中定义)不会引起问题。)

注意:我知道当代码在浏览器中运行时,这些类型将存在于运行时,但我希望 Deno 在编译时了解它们。

我尝试以某种方式包含 .d.ts 文件。我尝试过的事情:

  • "libs": ["deno.window", "esnext"]在编译器选项中指定等(在 deno.json 中)。
  • 像这样导入类型:
/// <reference types="https://raw.githubusercontent.com/microsoft/TypeScript/main/lib/lib.dom.d.ts" />
Run Code Online (Sandbox Code Playgroud)
  • 或这个:
// @deno-types="https://raw.githubusercontent.com/microsoft/TypeScript/main/lib/lib.dom.d.ts"
Run Code Online (Sandbox Code Playgroud)

其中一些尝试根本不起作用,有些甚至明显没有被解析。看起来我不明白 Deno 如何加载类型定义,例如它Path2D从哪里加载类型声明。如何解决这个问题?

jse*_*ksn 5

在对程序进行类型检查时,您需要将 Deno 配置为使用DOM 和 ES 类型。您可以使用 Deno 配置文件中支持的 TypeScript 编译器选项来执行此操作:

./deno.json:

{
  "compilerOptions": {
    "lib": [
      "esnext",
      "dom",
      "dom.iterable"
    ]
  }
}

Run Code Online (Sandbox Code Playgroud)

这指示编译器该程序不会在 Deno 中运行,而是在具有这些环境全局类型的类似浏览器的环境中运行。

这是一个示例源文件:

./main.ts

import {assertExists} from 'https://deno.land/std@0.126.0/testing/asserts.ts';

const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
assertExists(ctx);

Run Code Online (Sandbox Code Playgroud)

当您从其他 TypeScript 模块导入到这样的模块时,

  • 将由 Deno 编译,并且
  • 注定要在类似浏览器的环境中执行

那么你必须捆绑结果,因为浏览器无法将 TypeScript 源模块作为导入处理:

deno bundle --config deno.json main.ts main.js
Run Code Online (Sandbox Code Playgroud)

生成的 JavaScript 看起来像这样:

deno bundle --config deno.json main.ts main.js
Run Code Online (Sandbox Code Playgroud)

https://deno.land/std@0.126.0/testing/asserts.ts在程序编译中使用该模块是安全的,因为它会在尝试使用其任何 API 之前对 Deno 命名空间进行运行时功能检测。任何不这样做的模块都会导致运行时错误。