使用 Deno API 时出现 TSC 编译错误(TS2307)

问题描述 投票:0回答:1

我有一个小的ts项目,应该编译成js。 由于我不知道将运行哪个运行时(Deno、Bun 或 Node),我确实需要将其编译为 js 而无法使用 Deno 内置编译器。

当我现在尝试编译时,编译器抛出错误:

 error TS2304: Cannot find name 'Deno'.

Line 34                 version: Deno.version.deno

这是我的 tsconfig 文件:

{
  "compilerOptions": {
    "sourceMap": true,
    "target": "es6",
    "strict": true,
    "esModuleInterop": true,
    "moduleResolution": "node",
    "baseUrl": "./src",
    "forceConsistentCasingInFileNames": true,
    "resolveJsonModule": true,
    "types": ["bun-types"]
  },
  "include": [
    "src/**/*.ts"
  ],
  "exclude": [
    "node_modules"
  ]
}

你知道我该如何解决这个问题吗?

我知道我可以在之前添加

// @ts-ignore
,但我更愿意找到合适的配置。

提前谢谢你!

typescript tsc deno
1个回答
0
投票

在编写 同构 TypeScript(针对多个运行时/环境)时,如果不使用 特征检测,您将无法可靠地依赖于并非 对每个环境都通用 的任何值。正因为如此,您还不能在编译期间安全地包含任何环境库类型——例如:像 Node.js (

@types/node
)、Bun (
bun-types
)、Deno (
deno.ns
,
deno.window) 这样的类型
等)、浏览器/DOM(
@types/web
dom
dom.iterable
等)或其他——这使它变得更加复杂。

TypeScript 提供了一个名为 type predicates 的有用特性,它可以与类型保护函数一起使用以在运行时执行这些类型的验证——它们还会通知编译器值是预期类型并且可以安全使用.

您可以在项目的 GitHub 存储库中引用 Deno 命名空间类型声明——例如,在我写这个答案时,这是指向当前 CLI 版本的

Deno.version.deno
行的直接链接 (
v1.32.4
):https:// github.com/denoland/deno/blob/v1.32.4/cli/tsc/dts/lib.deno.ns.d.ts#L4708

在您的代码中,您可以像这样对 Deno 版本值进行特征检测:

./src/example.mts

// The following triple-slash directives aren't necessary when using
// the TSConfig in this answer, but I'm including them here so that the module
// can be type-checked in isolation, apart from the config file (e.g. by Deno):
/// <reference no-default-lib="true" />
/// <reference lib="esnext" />
/// <reference path="./types/global.d.ts" />

function isObject<T>(value: T): value is T & object {
  return typeof value === "object" && value != null;
}

// There's a global Deno variable
if ("Deno" in globalThis) {
  // But we don't yet know what type it is
  const { Deno } = globalThis as Record<string, unknown>;
  // It's an object
  if (isObject(Deno)) {
    // And it has a "version" key that's also an object
    if ("version" in Deno && isObject(Deno.version)) {
      // And that object has a "deno" key that's a string
      if ("deno" in Deno.version && typeof Deno.version.deno === "string") {
        // Only in this scope can we safely access it with confidence
        console.log("Deno version:", Deno.version.deno);
      } else {
        console.log(`There's no "deno" string key in Deno.version`);
      }
    } else {
      console.log(`There's no "version" object key in Deno`);
    }
  } else {
    console.log("Deno is not an object");
  }
} else {
  console.log("There's no global Deno");
}


为了完整起见,以下是我的复制目录中针对您的问题的其他文件:

./package.json

{
  "name": "so-76034796",
  "version": "0.1.0",
  "type": "module",
  "scripts": {
    "compile": "tsc"
  },
  "devDependencies": {
    "typescript": "^5.0.4"
  }
}

./tsconfig.json

{
  "compilerOptions": {
    "strict": true,
    "exactOptionalPropertyTypes": true,
    "noImplicitOverride": true,
    "noImplicitReturns": true,
    "noUncheckedIndexedAccess": true,

    "removeComments": true,
    // "inlineSourceMap": true,
    // "inlineSources": true,

    "forceConsistentCasingInFileNames": true,

    "module": "esnext",
    "moduleDetection": "force",
    "moduleResolution": "nodenext",
    // "moduleResolution": "bundler",
    // "allowImportingTsExtensions": true,
    "isolatedModules": true,
    "esModuleInterop": true,

    "target": "esnext",
    "lib": ["esnext"],

    // "jsx": "react-jsx",

    "outDir": "dist",
    // "noEmit": true,

    "typeRoots": ["./src/types"]
  },
  "include": ["src/**/*"]
}

我从控制台 API 中包含了这些类型,因为它在所有提到的目标环境中都可用。否则,您还需要对其进行特征检测:

./src/types/global.d.ts

/**
 * @see https://github.com/microsoft/TypeScript/blob/v5.0.4/lib/lib.dom.d.ts#L17498
 * 
 * For Node.js, refer to:
 * - [global](https://github.com/DefinitelyTyped/DefinitelyTyped/blob/04c9ac7555c9fd1562aea37475af4e176db0019a/types/node/globals.d.ts#L28)
 * - [console](https://github.com/DefinitelyTyped/DefinitelyTyped/blob/04c9ac7555c9fd1562aea37475af4e176db0019a/types/node/console.d.ts#L66)
 */
interface Console {
  assert(condition?: boolean, ...data: any[]): void;
  clear(): void;
  count(label?: string): void;
  countReset(label?: string): void;
  debug(...data: any[]): void;
  dir(item?: any, options?: any): void;
  dirxml(...data: any[]): void;
  error(...data: any[]): void;
  group(...data: any[]): void;
  groupCollapsed(...data: any[]): void;
  groupEnd(): void;
  info(...data: any[]): void;
  log(...data: any[]): void;
  table(tabularData?: any, properties?: string[]): void;
  time(label?: string): void;
  timeEnd(label?: string): void;
  timeLog(label?: string, ...data: any[]): void;
  timeStamp(label?: string): void;
  trace(...data: any[]): void;
  warn(...data: any[]): void;
}

declare var console: Console;

使用 vanilla 进行编译

tsc
并在 Node 和 Deno 中运行:

so-76034796 % npm install

added 1 package, and audited 2 packages in 445ms

found 0 vulnerabilities

so-76034796 % npm run compile

> [email protected] compile
> tsc

so-76034796 % deno check src/example.mts

so-76034796 % deno run src/example.mts
Deno version: 1.32.4

so-76034796 % deno run dist/example.mjs
Deno version: 1.32.4

so-76034796 % node dist/example.mjs
There's no global Deno

so-76034796 % node --version
v18.16.0

so-76034796 % npm --version
9.5.1

so-76034796 % deno --version
deno 1.32.4 (release, aarch64-apple-darwin)
v8 11.2.214.9
typescript 5.0.3

© www.soinside.com 2019 - 2024. All rights reserved.