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
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!");
},
};
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();
}
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();
}
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!
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();
}
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!
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)