You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

运行时提示Symbol.asyncDispose未定义的TypeScript问题求助

解决TypeScript中await using运行时Symbol.asyncDispose未定义的问题

问题场景

我实现了AsyncDisposable接口并使用await using语法,TypeScript配置已正确引入esnext.disposable库,但运行时抛出TypeError: Symbol.asyncDispose is not defined错误。

代码示例

export function loggy(id: string): AsyncDisposable {
    return {
        async [Symbol.asyncDispose]() {
            console.log(`Disposing (async) ${id}`);
            Promise.resolve().then(() => console.log(`Disposed (async) ${id}`));
        },
    };
}

async function foo () {
    await using k = loggy("asd");
};

foo();

TypeScript配置

{
    "$schema": "https://json.schemastore.org/tsconfig",
    "display": "Node 20",
    "_version": "20.1.0",

    "compilerOptions": {
        "lib": ["es2022", "esnext.disposable", "dom"],
        "module": "CommonJS",
        "target": "es2022",

        "strict": true,
        "esModuleInterop": true,
        "skipLibCheck": true,
        "forceConsistentCasingInFileNames": true
    },
    "include": ["./src", "./tests"]
}

错误信息

> ts-playground@1.0.0 main
> ts-node src/index.ts

/Users/eitan/git/ts-playground/src/index.ts:7
                },
                                            ^
TypeError: Symbol.asyncDispose is not defined.
    at __addDisposableResource (/Users/eitan/git/ts-playground/src/index.ts:7:45)
    at foo (/Users/eitan/git/ts-playground/src/index.ts:12:15)
    at Object.<anonymous> (/Users/eitan/git/ts-playground/src/index.ts:16:1)
    at Module._compile (node:internal/modules/cjs/loader:1218:14)
    at Module.m._compile (/Users/eitan/git/ts-playground/node_modules/ts-node/src/index.ts:1618:23)
    at Module._extensions..js (node:internal/modules/cjs/loader:1272:10)
    at Object.require.extensions.<computed> [as .ts] (/Users/eitan/git/ts-playground/node_modules/ts-node/src/index.ts:1621:12)
    at Module.load (node:internal/modules/cjs/loader:1081:32)
    at Function.Module._load (node:internal/modules/cjs/loader:922:12)
    at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:81:12)

原因分析

Symbol.asyncDispose和await using语法在Node.js 20.x版本中仍处于实验性阶段,默认未启用;即使TypeScript编译通过,运行时Node.js环境不会自动提供这个Symbol,导致报错。

解决方法

方法1:启用Node.js实验性标志运行

在启动命令中添加--experimental-async-disposables标志,让Node.js加载该实验性特性:

ts-node --experimental-async-disposables src/index.ts

如果使用npm脚本,修改package.json:

{
  "scripts": {
    "main": "ts-node --experimental-async-disposables src/index.ts"
  }
}

方法2:升级Node.js到21+版本

Node.js 21及以上版本中,Symbol.asyncDispose和异步可处置API已成为稳定特性,无需额外标志即可直接运行。

方法3:手动Polyfill Symbol.asyncDispose

在代码入口顶部添加Polyfill代码,手动定义Symbol.asyncDispose:

// 在index.ts最顶部添加
if (!Symbol.asyncDispose) {
  (Symbol as any).asyncDispose = Symbol.for('Symbol.asyncDispose');
}

// 后续代码不变
export function loggy(id: string): AsyncDisposable {
    // ...
}

该方法通过Symbol.for复用全局符号,确保运行时存在该Symbol定义。

方法4:切换到ESM模块模式

修改tsconfig.json的module为ESNext,并在package.json中添加"type": "module":

  1. 更新tsconfig.json:
{
  "compilerOptions": {
    "module": "ESNext",
    // 其他配置不变
  }
}
  1. 在package.json中添加:
{
  "type": "module"
}
  1. 运行命令改为:
ts-node --esm src/index.ts

ESM模式下Node.js对实验性特性的支持更完善,能避免CommonJS下的兼容性问题。

内容的提问来源于stack exchange,提问作者Eitank

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 04:57:31