{"record":{"id":"d52a25ec219293a2","repo":"swc-project/swc","slug":"using-declarations-can-only-be-used-with-objects","errorCode":null,"errorMessage":"using declarations can only be used with objects, functions, null, or undefined.","messagePattern":"using declarations can only be used with objects, functions, null, or undefined\\.","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"crates/swc_ecma_transforms_base/src/helpers/generated/_using.rs","lineNumber":15,"sourceCode":"// This file is generated by `cargo codegen helpers`. DO NOT MODIFY.\n\nuse super::{HelperDef, HelperName};\n\npub const DEF: HelperDef = HelperDef {\n    name: HelperName::using,\n    local: \"_using\",\n    import_path: \"@swc/helpers/_/_using\",\n    #[cfg(feature = \"inline-helpers\")]\n    source: r#\"/* @minVersion 7.22.0 */\n\nfunction _using(stack, value, isAwait) {\n    if (value === null || value === void 0) return value;\n    if (Object(value) !== value) {\n        throw new TypeError(\"using declarations can only be used with objects, functions, null, or undefined.\");\n    }\n    // core-js-pure uses Symbol.for for polyfilling well-known symbols\n    if (isAwait) {\n        var dispose = value[Symbol.asyncDispose || Symbol.for(\"Symbol.asyncDispose\")];\n    }\n    if (dispose === null || dispose === void 0) {\n        dispose = value[Symbol.dispose || Symbol.for(\"Symbol.dispose\")];\n    }\n    if (typeof dispose !== \"function\") {\n        throw new TypeError(`Property [Symbol.dispose] is not a function.`);\n    }\n    stack.push({ v: value, d: dispose, a: isAwait });\n    return value;\n}\n\"#,\n    #[cfg(feature = \"inline-helpers\")]\n    deps: super::HelperBitmap::from_bits(0x00000010000000000000000000000000),\n};","sourceCodeStart":1,"sourceCodeEnd":33,"githubUrl":"https://github.com/swc-project/swc/blob/5176682b65416c6b5de6b47379ae1588ea3ecb3f/crates/swc_ecma_transforms_base/src/helpers/generated/_using.rs#L1-L33","documentation":"`_using` is the helper SWC emits for `using` declarations under explicit-resource-management downleveling (min ES 7.22 per its header). It rejects primitives with `Object(value) !== value` and throws `TypeError: using declarations can only be used with objects, functions, null, or undefined.` — the spec rule that resources must be disposable objects.","triggerScenarios":"`using x = 42;` / `using s = 'str';` / any primitive resource in code whose `using` declarations were compiled to `_using` (Babel-compatible output from SWC's compat pass).","commonSituations":"Adopting the `using` proposal with wrapper libraries (like TypeScript's TempFile examples) but letting a primitive slip in from a union-typed acquire function; refactoring try/finally cleanup to `using` where the resource is a number handle.","solutions":["Restrict `using` to objects/functions implementing `[Symbol.dispose]` (or null/undefined for no-op scoping).","Wrap primitive handles: `using h = { [Symbol.dispose]: () => closeHandle(id), id };`.","Keep primitives in `try/finally` blocks and use `using` only for object resources.","Narrow the acquire function's return type so primitives are rejected at compile time."],"exampleFix":"// before\nusing handleId = acquireHandle(); // acquireHandle(): number\n// TypeError: using declarations can only be used with objects, functions, null, or undefined.\n\n// after\nconst id = acquireHandle();\nusing handle = { [Symbol.dispose]: () => releaseHandle(id) };","handlingStrategy":"type-guard","validationCode":"// Same rule as _using: Object(value) === value, or null/undefined.\nconst isUsingCompatible = (v) => v === null || v === undefined || Object(v) === v;\nconst res = acquire();\nif (!isUsingCompatible(res)) {\n  throw new TypeError(`using got primitive ${typeof res} — wrap it in a disposable object`);\n}","typeGuard":"const isUsingCompatible = (v: unknown): v is object | null | undefined =>\n  v == null || (typeof v === 'object' || typeof v === 'function');","tryCatchPattern":null,"preventionTips":["Keep acquire functions' return types narrow (`Disposable | null`) so primitives are a compile-time error.","Do not use `|| 0`-style primitive fallbacks in `using` initializers.","Wrap primitive handles (fds, ids) in a `{ [Symbol.dispose] }` adapter at the boundary."],"tags":["using-declaration","explicit-resource-management","disposable","typeerror"],"backgroundTag":"using-declaration-non-object","analyzedSha":"5176682b65416c6b5de6b47379ae1588ea3ecb3f","analyzedAt":"2026-08-17T16:16:52.067Z","contentChangedAt":"2026-08-17T16:16:52.067Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}