Skip to content
Tech News
← Back to articles

Adding Go's Defer to the TypeScript Compiler

read original more articles
Why This Matters

This article explores the feasibility of integrating Go's defer statement into the TypeScript compiler, highlighting both the technical challenges and the potential benefits of more expressive resource management in TypeScript. While technically possible, the author suggests that such an addition may not be advisable, emphasizing the importance of language design choices in the broader tech ecosystem.

Key Takeaways

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