Defer in TypeScript
In TypeScript, there isn’t a direct equivalent to the defer
keyword. However, we can achieve similar functionality using the try...finally
block or by implementing a custom defer mechanism. Let’s look at both approaches:
- Using
try...finally
:
import * as fs from 'fs';
function main() {
let file: fs.WriteStream | null = null;
try {
file = createFile("/tmp/defer.txt");
writeFile(file);
} finally {
if (file) {
closeFile(file);
}
}
}
function createFile(p: string): fs.WriteStream {
console.log("creating");
return fs.createWriteStream(p);
}
function writeFile(f: fs.WriteStream) {
console.log("writing");
f.write("data\n");
}
function closeFile(f: fs.WriteStream) {
console.log("closing");
f.close((err) => {
if (err) {
console.error(`error: ${err}`);
process.exit(1);
}
});
}
main();
- Implementing a custom defer mechanism:
import * as fs from 'fs';
class Defer {
private actions: (() => void)[] = [];
add(fn: () => void) {
this.actions.push(fn);
}
run() {
while (this.actions.length) {
const action = this.actions.pop();
if (action) action();
}
}
}
function main() {
const defer = new Defer();
const file = createFile("/tmp/defer.txt");
defer.add(() => closeFile(file));
writeFile(file);
defer.run();
}
function createFile(p: string): fs.WriteStream {
console.log("creating");
return fs.createWriteStream(p);
}
function writeFile(f: fs.WriteStream) {
console.log("writing");
f.write("data\n");
}
function closeFile(f: fs.WriteStream) {
console.log("closing");
f.close((err) => {
if (err) {
console.error(`error: ${err}`);
process.exit(1);
}
});
}
main();
In both examples, we’re using the fs
module to work with files. The createFile
function creates a write stream, writeFile
writes to the stream, and closeFile
closes the stream.
In the first approach, we use a try...finally
block to ensure that the file is closed even if an error occurs during writing.
In the second approach, we implement a custom Defer
class that mimics the behavior of the defer
keyword. Actions are added to the Defer
instance and executed in reverse order when run()
is called.
To run the program:
$ ts-node defer.ts
creating
writing
closing
This confirms that the file is closed after being written, similar to the original example.
Note that TypeScript doesn’t have a direct equivalent to panic
, so error handling is done through exceptions or by passing errors to callbacks, as is common in Node.js.