I wanted to see how difficult it would be to add Go's defer statement to the TypeScript compiler, but by the time I finished I was convinced it probably shouldn't exist.
In Go, the defer statement delays the execution of a function until the surrounding function finishes. It's most commonly used to keep resource acquisition and cleanup together, like acquiring a semaphore:
func withSemaphore ( ctx context . Context , sem * semaphore . Weighted ) error { if err := sem . Acquire ( ctx , 1 ) ; err != nil { return err } defer sem . Release ( 1 ) // ... protected work return nil }
TypeScript doesn't have a strict equivalent of defer . You might use try / finally , like:
async function readFile ( path : string ) { await sema . acquire ( ) ; try { // ... use resource } finally { sema . release ( ) ; } }
But that's kinda ugly.
For fun, we can hack in a defer statement to the TypeScript compiler and get Go-like semantics. Since defer doesn't map to an existing JavaScript feature, we need to output JavaScript code that makes it work at runtime just like it does in Go.
So the goal is to be able to write TypeScript code like this:
async function readFile ( path : string ) { await sema . acquire ( ) ; defer sema . release ( ) ; // New! // ... use resource }
The TypeScript Compiler
... continue reading