我有一个小的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(针对多个运行时/环境)时,如果不使用 特征检测,您将无法可靠地依赖于并非 对每个环境都通用 的任何值。正因为如此,您还不能在编译期间安全地包含任何环境库类型——例如:像 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