> ## Documentation Index
> Fetch the complete documentation index at: https://docs.syntblaze.com/llms.txt
> Use this file to discover all available pages before exploring further.

# TypeScript await using Declaration

The `await using` declaration is a block-scoped variable declaration that implements asynchronous Explicit Resource Management. It guarantees that an object's cleanup logic is automatically awaited and executed when the execution context exits the block in which the variable is declared, regardless of whether the block exits normally or throws an exception.

To utilize `await using`, the assigned value typically conforms to the `AsyncDisposable` interface by implementing a method keyed by the well-known symbol `Symbol.asyncDispose`. However, `await using` also accepts objects that only implement the synchronous `Disposable` interface (`Symbol.dispose`), as well as `null` or `undefined` (which safely perform no disposal).

## Syntax and Interfaces

Under the hood, TypeScript defines the disposal interfaces as follows:

```typescript theme={"dark"}
interface AsyncDisposable {
    [Symbol.asyncDispose](): PromiseLike<void>;
}

interface Disposable {
    [Symbol.dispose](): void;
}
```

When you declare a variable with `await using`, TypeScript enforces that the variable is immutable (implicitly `const`). At the end of the lexical scope, the runtime schedules the `[Symbol.asyncDispose]()` method to be awaited. If a synchronous `Disposable` is provided instead, its `[Symbol.dispose]()` method is executed and its completion is awaited via a resolved Promise.

```typescript theme={"dark"}
class AsyncResource implements AsyncDisposable {
    async [Symbol.asyncDispose](): Promise<void> {
        // Asynchronous teardown logic executes here
    }
}

async function execute() {
    await using asyncRes = new AsyncResource();
    await using syncRes = { [Symbol.dispose]: () => {} }; // Valid
    await using emptyRes = null; // Valid, acts as a no-op
    
    // Execution logic
    
} // Implicitly awaits the disposal of all declared resources
```

Because the disposal phase is asynchronous, `await using` declarations can only be utilized within `async` functions, `async` generators, or modules supporting top-level `await`.

## Execution Order

When multiple `await using` (or synchronous `using`) declarations exist within the same scope, their disposal methods are pushed onto a stack. Upon scope exit, they are awaited and executed in reverse order of their declaration (Last-In, First-Out).

```typescript theme={"dark"}
async function stackDisposal() {
    await using res1 = new AsyncResource();
    await using res2 = new AsyncResource();
} 
// 1. await res2[Symbol.asyncDispose]()
// 2. await res1[Symbol.asyncDispose]()
```

## Exception Handling and `SuppressedError`

The `await using` declaration introduces specific control flow mechanics for error handling. If an exception is thrown during the execution of the block, the disposal methods are still guaranteed to run.

If the disposal method *also* throws an exception while handling the original exception, the runtime prevents the original error from being silently swallowed. Instead, it throws a `SuppressedError`.

Because caught errors in modern TypeScript are of type `unknown`, you must use a type guard to safely access the properties of the `SuppressedError`.

```typescript theme={"dark"}
class FaultyResource implements AsyncDisposable {
    async [Symbol.asyncDispose]() {
        throw new Error("Disposal failed");
    }
}

async function errorHandling() {
    try {
        await using resource = new FaultyResource();
        throw new Error("Execution failed");
    } catch (err: unknown) {
        if (err instanceof SuppressedError) {
            // err.error holds the Error instance thrown during disposal
            // err.error.message === "Disposal failed"
            
            // err.suppressed holds the original execution Error instance
            // err.suppressed.message === "Execution failed"
        }
    }
}
```

## Compiler Configuration

To use `await using` in TypeScript, the environment must support the underlying ECMAScript proposal. If targeting older runtimes, you must configure the TypeScript compiler to recognize the global symbols:

```json theme={"dark"}
// tsconfig.json
{
  "compilerOptions": {
    "target": "ES2022",
    "lib": ["ES2022", "ESNext.Disposable"]
  }
}
```

In environments where `Symbol.asyncDispose`, `Symbol.dispose`, and `SuppressedError` are not natively implemented, global polyfills must be provided at runtime before the `await using` declaration is evaluated.

<div
  style={{ 
display: "flex", 
justifyContent: "space-between", 
alignItems: "center", 
maxWidth: "754px", 
padding: "1rem 0",
marginBottom: "24px"
}}
>
  <span style={{ fontWeight: "bold", fontSize: "1.25rem", color: "var(--tw-prose-headings)", fontFamily: "Inter, ui-sans-serif, system-ui, sans-serif" }}>Tired of Poor TypeScript Skills? Fix That With Deep Grasping!</span>

  <a
    href="https://syntblaze.com"
    target="_blank"
    style={{ 
  marginLeft: "24px",
  textDecoration: "none", 
  backgroundColor: "#007AFF",
  color: "#ffffff", 
  padding: "6px 16px", 
  borderRadius: "16px",
  fontSize: "0.9rem",
  fontWeight: "600",
  textAlign: "center",
  transition: "background-color 0.2s ease"
}}
  >
    Learn More
  </a>
</div>

<div style={{ display: "flex", gap: "12px", flexWrap: "wrap" }}>
  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/skill-tracking.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=b9b0305c93bb501c9e767b5c76c88835" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/skill-tracking.png" />

  <img src="https://mintcdn.com/syntblazellc/23tyuOzaWS88qFlc/images/nuggets.png?fit=max&auto=format&n=23tyuOzaWS88qFlc&q=85&s=c86c80197299762989e9b882419b2109" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/nuggets.png" />

  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/bite-sized-exercises.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=a65f9a38c37ff28ab73ed783c53c60e3" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/bite-sized-exercises.png" />
</div>

<div style={{ display: "flex", gap: "12px", flexWrap: "wrap", marginTop: "12px" }}>
  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/mastery-chain.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=748a1763454713e679260fbb95f154a2" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/mastery-chain.png" />

  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/element-previews.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=242f61448ff5dd6deaaab2dccc13b507" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/element-previews.png" />

  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/element-explanations.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=cf0fc1c31f9cd0fc26716781be05fbc9" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/element-explanations.png" />
</div>
