Over 10 years we help companies reach their financial and branding goals. Engitech is a values-driven technology agency dedicated.

Gallery

Contacts

411 University St, Seattle, USA

engitech@oceanthemes.net

+1 -800-456-478-23

Blog

TypeScript 5.2 is set to introduce a fresh keyword called ‘using,’ which will provide a convenient way to dispose of objects having a Symbol.dispose function when they go out of scope.

Here’s an example showcasing the usage of the new ‘using’ keyword:

{

  const getResource = () => {

    return {

      [Symbol.dispose]: () => {

        console.log('Hooray!')

      }

    }

  }

  using resource = getResource();

} // 'Hooray!' message will be logged to the console

The addition of ‘using’ is based on a TC39 proposal, which has recently advanced to Stage 3, indicating its forthcoming inclusion in JavaScript.

The ‘using’ keyword will prove highly valuable in resource management scenarios such as handling file handles, database connections, and more efficiently.

A key component enabling this functionality is the Symbol.dispose symbol, which serves as a global symbol in JavaScript. When an object has a function assigned to Symbol.dispose, it is considered a ‘resource’—an object with a specific lifespan—and can be used alongside the ‘using’ keyword.

For instance, defining a resource object with Symbol.dispose can be done as follows:

const resource = {

  [Symbol.dispose]: () => {

    console.log("Hooray!");

  },

};

Additionally, when dealing with resources that require asynchronous disposal, Symbol.asyncDispose and ‘await using’ can be utilized:

const getResource = () => ({

  [Symbol.asyncDispose]: async () => {

    await someAsyncFunc();

  },

});

{

  await using resource = getResource();

}

By using ‘await using,’ the execution will pause to await the completion of the Symbol.asyncDispose function before proceeding further. This is particularly beneficial for managing resources like database connections, ensuring proper closure before the program continues.

Here are a couple of use cases to illustrate the practical applications of the ‘using’ keyword:

  1. File handles: Accessing the file system and utilizing file handles in Node.js can be made more straightforward with ‘using.’

Without ‘using’:

import { open } from "node:fs/promises";

let filehandle;

try {

  filehandle = await open("thefile.txt", "r");

} finally {

  await filehandle?.close();

}

With ‘using’:

import { open } from "node:fs/promises";

const getFileHandle = async (path: string) => {

  const filehandle = await open(path, "r");

  return {

    filehandle,

    [Symbol.asyncDispose]: async () => {

      await filehandle.close();

    },

  };

};

{

  await using file = getFileHandle("thefile.txt");

  // Perform operations with file.filehandle

} // Automatic disposal!
  1. Database connections: Managing database connections is a common use case for utilizing ‘using,’ similar to its usage in C#.

Without ‘using’:

const connection = await getDb();

try {

  // Perform operations with connection

} finally {

  await connection.close();

}

With 'using':

const getConnection = async () => {

  const connection = await getDb();

  return {

    connection,

    [Symbol.asyncDispose]: async () => {

      await connection.close();

    },

  };

};

{

  await using { connection } = getConnection();

  // Perform operations with connection

} // Automatic closure!

In both examples, the ‘using’ keyword ensures that the resources are automatically managed and properly disposed of without the need for explicit cleanup code.