swc-project/swc · error · TypeError
Object expected.
Error message
Object expected.
What it means
`_ts_add_disposable_resource` backs TypeScript `using`/`await using` declarations that SWC downlevels for old targets. Explicit resource management only accepts objects, functions, `null`, and `undefined`; passing a primitive triggers `TypeError("Object expected.")` because primitives cannot carry `[Symbol.dispose]`.
Source
Thrown at crates/swc_ecma_transforms_base/src/helpers/generated/_ts_add_disposable_resource.rs:13
// This file is generated by `cargo codegen helpers`. DO NOT MODIFY.
use super::{HelperDef, HelperName};
pub const DEF: HelperDef = HelperDef {
name: HelperName::ts_add_disposable_resource,
local: "_ts_add_disposable_resource",
import_path: "@swc/helpers/_/_ts_add_disposable_resource",
#[cfg(feature = "inline-helpers")]
source: r#"function _ts_add_disposable_resource(env, value, async) {
if (value !== null && value !== void 0) {
if (typeof value !== "object" && typeof value !== "function") {
throw new TypeError("Object expected.");
}
var dispose, inner;
if (async) {
if (!Symbol.asyncDispose) {
throw new TypeError("Symbol.asyncDispose is not defined.");
}
dispose = value[Symbol.asyncDispose];
}
if (dispose === void 0) {
if (!Symbol.dispose) {
throw new TypeError("Symbol.dispose is not defined.");
}
dispose = value[Symbol.dispose];
if (async) {
inner = dispose;
}
}
if (typeof dispose !== "function") {View on GitHub (pinned to 5176682b65)
Solutions
- Only use `using`/`await using` with disposable resources — objects or functions exposing `[Symbol.dispose]`/`[Symbol.asyncDispose]` — plus `null`/`undefined`.
- If you need cleanup around a primitive, wrap it: `using box = { [Symbol.dispose]: () => cleanup(), value };`.
- Use plain `try/finally` for primitives instead of `using`.
Example fix
// before
function run() {
using handle = getHandle(); // returns 42 for some inputs
// TypeError: Object expected.
}
// after
function run() {
const handle = getHandle();
if (typeof handle === 'number') { /* primitive path, no using */ return; }
using h = handle; // now provably an object
} Defensive patterns
Strategy: type-guard
Validate before calling
// Mirror the helper's own rule before the `using` statement.
const isUsableResource = (v) =>
v === null || v === undefined || typeof v === 'object' || typeof v === 'function';
const res = acquire();
if (!isUsableResource(res)) {
throw new TypeError(`using requires an object/function/null/undefined, got ${typeof res}`);
}
using r = res; Type guard
type UsableResource = Disposable | AsyncDisposable | null | undefined; const isUsableResource = (v: unknown): v is UsableResource => v == null || typeof v === 'object' || typeof v === 'function';
Prevention
- Type acquire functions as `Disposable | null | undefined` so primitives fail at compile time.
- Reserve `using` for resources with real disposal semantics; use try/finally for scalar cleanup flags.
- Wrap unavoidable primitive handles in a `{ [Symbol.dispose]: ... }` adapter at acquisition.
When it happens
Trigger: `using x = 42;`, `using s = 'text';`, or an acquire function that conditionally returns a primitive, compiled with `using` declarations for a target without native support (Node < 20 / ES2022-).
Common situations: Trying to abuse `using` as a generic scope-exit hook for primitives; a `getHandle()` whose return type union includes primitives; TS 5.2+ code compiled for older runtimes.
Related errors
- Object not disposable.
- using declarations can only be used with objects, functions,
- Property [Symbol.dispose] is not a function.
- Symbol.dispose is not defined.
- using declarations can only be used with objects, functions,
AI-assisted analysis of swc-project/swc@5176682b65 (2026-08-17).
Data as JSON: /api/errors/6be7610c330c2d53.
Report an issue: GitHub.