Skip to content

Instantly share code, notes, and snippets.

@dsherret
Last active October 26, 2023 13:30
Show Gist options
  • Save dsherret/cf5d6bec3d0f791cef00 to your computer and use it in GitHub Desktop.
Save dsherret/cf5d6bec3d0f791cef00 to your computer and use it in GitHub Desktop.
Typescript Disposable (using statement)
// NOTE: This is now rolled up in a package and supports more scenarios: https://github.com/dsherret/using-statement
interface IDisposable {
dispose();
}
function using<T extends IDisposable>(resource: T, func: (resource: T) => void) {
try {
func(resource);
} finally {
resource.dispose();
}
}
// Example use:
class Camera implements IDisposable {
takePicture() { /* omitted */ }
// etc...
dispose() {
navigator.camera.cleanup();
}
}
using(new Camera(), (camera) => {
camera.takePicture();
});
@SteveStrong
Copy link

very well done

@nite
Copy link

nite commented May 8, 2018

Just came here via a google search - any chance this is in the typescript future spec?

@maca134
Copy link

maca134 commented Jul 15, 2018

Here is a modification i made to it, so it works with async/await

/**
 * Provides a mechanism for releasing resources.
 */
export interface IDisposable {
    dispose(): Promise<void>;
}

/**
 * Provides a convenient syntax that ensures the correct use of IDisposable objects
 */
export async function using<T extends IDisposable>(resource: T, func: (resource: T) => Promise<void>) {
    try {
        await func(resource);
    } finally {
        await resource.dispose();
    }
}

// example

(async () => {
    await using(ioc.get<IUdpClient>(types.IUdpClient), async (client) => {
        client.connect(endpoint);
        client.send({toBuffer: () => Buffer.from("hello world1")});
        let response = await client.receive();
        console.log(response);

        await Task.delay(1000);
        client.send({toBuffer: () => Buffer.from("hello world2")});
        response = await client.receive();
        console.log(response);


        console.log("using complete");
    });
    console.log("end");
})();

@stherrienaspnet
Copy link

Really nice!

@mxs42
Copy link

mxs42 commented Oct 24, 2018

Very very nice, good and elegant solutions.

@zewa666
Copy link

zewa666 commented Feb 1, 2019

Awesome idea. @nite take a look at this beauty https://github.com/tc39/proposal-using-statement

@fitfinderaustralia
Copy link

Very cool. Have you considered turning this into an NPM module? I agree that it should be a language construct.

@dsherret
Copy link
Author

dsherret commented May 9, 2019

@fitfinderaustralia done and it supports more scenarios such as async and generator functions: https://github.com/dsherret/using-statement

@fitfinderaustralia
Copy link

Great work - I love it!

@giano
Copy link

giano commented Sep 2, 2020

Great!

@GokselKUCUKSAHIN
Copy link

Appreciated 👏.

@guftall
Copy link

guftall commented Jan 12, 2022

Nice

@maca134 in case you want to return a value from it

export async function using<T extends IDisposable, U>(resource: T, func: (resource: T) => Promise<U>) {
    try {
        return await func(resource);
    } finally {
        await resource.dispose();
    }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment