我正在使用 Deno 编译一些 TypeScript,然后将其作为网页的一部分提供,以便它在浏览器端运行。我正在尝试在客户端使用画布元素,为此我需要
CanvasRenderingContext2D
或 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" />
// @deno-types="https://raw.githubusercontent.com/microsoft/TypeScript/main/lib/lib.dom.d.ts"
其中一些尝试根本不起作用,有些甚至没有明显解析。看起来我不明白 Deno 如何加载类型定义,例如它从哪里加载
Path2D
类型声明。如何解决这个问题?
在对程序进行类型检查时,您需要将 Deno 配置为“仅”使用 DOM 和 ES 类型。您可以使用 Deno 配置文件中支持的 TypeScript 编译器选项来执行此操作:
./deno.json
:
{
"compilerOptions": {
"lib": [
"esnext",
"dom",
"dom.iterable"
]
}
}
这指示编译器该程序不会在 Deno 中运行,而是在具有这些环境全局类型的类似浏览器的环境中运行。
这是一个示例源文件:
./main.ts
import {assertExists} from 'https://deno.land/[email protected]/testing/asserts.ts';
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
assertExists(ctx);
当您从其他 TypeScript 模块导入到这样的模块中时
将由 Deno 编译,并且
deno bundle --config deno.json main.ts main.js
生成的 JavaScript 如下所示:
// deno-fmt-ignore-file
// deno-lint-ignore-file
// This code was bundled using `deno bundle` and it's not recommended to edit it manually
const { Deno } = globalThis;
typeof Deno?.noColor === "boolean" ? Deno.noColor : true;
new RegExp([
"[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:[a-zA-Z\\d]*(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?\\u0007)",
"(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-ntqry=><~]))",
].join("|"), "g");
var DiffType;
(function(DiffType1) {
DiffType1["removed"] = "removed";
DiffType1["common"] = "common";
DiffType1["added"] = "added";
})(DiffType || (DiffType = {}));
class AssertionError extends Error {
name = "AssertionError";
constructor(message){
super(message);
}
}
function assertExists(actual, msg) {
if (actual === undefined || actual === null) {
if (!msg) {
msg = `actual: "${actual}" expected to not be null or undefined`;
}
throw new AssertionError(msg);
}
}
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
assertExists(ctx);
在程序编译中使用
https://deno.land/[email protected]/testing/asserts.ts
处的模块是安全的,因为它在尝试使用其任何 API 之前会对 Deno 命名空间进行运行时功能检测。任何不这样做的模块都会导致运行时错误。
/// <reference lib="dom" />
如果您想为项目定义它,可以使用它
deno.json
{
"compilerOptions": {
"lib": [
"dom"
]
}
}