DEV Community

lingfei1999
lingfei1999

Posted on

Typescript 5.2 - Using

TypeScript 5.2 is set to introduce a new keyword called 'using', which allows you to dispose of resources with a Symbol.dispose function when they go out of scope.

Here's an example of how it works:

{
    const getResource = () => {
        return {
            [Symbol.dispose]: () => {
            console.log('Hooray!');
        }
    };
}
using resource = getResource();
} // 'Hooray!' logged to console
Enter fullscreen mode Exit fullscreen mode

This feature is based on the TC39 proposal, which has recently reached Stage 3, indicating its upcoming inclusion in JavaScript.

The 'using' keyword will be particularly valuable for managing resources such as file handles, database connections, and more.

Symbol.dispose is a new global symbol in JavaScript. By assigning a function to Symbol.dispose, any object becomes a 'resource' – an object with a specific lifetime – that can be utilized with the 'using' keyword.

Here's an example of using Symbol.dispose:

const resource = {
    [Symbol.dispose]: () => {
        console.log("Hooray!");
    },
};
Enter fullscreen mode Exit fullscreen mode

Additionally, TypeScript 5.2 will support Symbol.asyncDispose and 'await using' for handling asynchronously disposed resources.

For example:

const getResource = () => ({
    [Symbol.asyncDispose]: async () => {
        await someAsyncFunc();
    },
});

{
    await using resource = getResource();
}
Enter fullscreen mode Exit fullscreen mode

The above code will await the Symbol.asyncDispose function before continuing, making it useful for resources that require asynchronous disposal, such as database connections.

Here are a couple of use cases for the 'using' keyword:

File handles: Accessing the file system with file handles in Node.js becomes easier with 'using'.
Without 'using':

import { open } from "node:fs/promises";
let filehandle;
  try {
    filehandle = await open("thefile.txt", "r");
  } finally {
    await filehandle?.close();
  }
Enter fullscreen mode Exit fullscreen mode

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");
// Do stuff with file.filehandle
} // Automatically disposed!
Enter fullscreen mode Exit fullscreen mode

Database connections: Managing database connections becomes more streamlined with 'using'.
Without 'using':

const connection = await getDb();
try {
    // Do stuff with connection
} finally {
    await connection.close();
}
Enter fullscreen mode Exit fullscreen mode

With 'using':

const getConnection = async () => {
    const connection = await getDb();
    return {
        connection,
        [Symbol.asyncDispose]: async () => {
            await connection.close();
        },
    };
};

{
    await using { connection } = getConnection();
// Do stuff with connection
} // Automatically closed!
Enter fullscreen mode Exit fullscreen mode

Overall, the 'using' keyword in TypeScript 5.2 simplifies resource management by allowing automatic disposal of resources when they go out of scope, enhancing code clarity and reducing the chances of resource leaks.

https://www.open-consulting.co/writing/engineering/typescript_using

Top comments (0)