Directories in TypeScript

Here’s the translation of the Go code to TypeScript, along with explanations in Markdown format suitable for Hugo:

TypeScript provides several useful functions for working with directories in the file system. Let’s explore how to handle directories using TypeScript and the Node.js fs and path modules.

import * as fs from 'fs';
import * as path from 'path';

function check(e: Error | null) {
    if (e) {
        throw e;
    }
}

function main() {
    // Create a new sub-directory in the current working directory.
    fs.mkdirSync('subdir', { mode: 0o755 });

    // When creating temporary directories, it's good practice to
    // use a try-finally block to ensure cleanup.
    try {
        // Helper function to create a new empty file.
        const createEmptyFile = (name: string) => {
            fs.writeFileSync(name, '', { mode: 0o644 });
        };

        createEmptyFile('subdir/file1');

        // We can create a hierarchy of directories, including
        // parents with mkdirSync and the recursive option.
        // This is similar to the command-line `mkdir -p`.
        fs.mkdirSync('subdir/parent/child', { recursive: true, mode: 0o755 });

        createEmptyFile('subdir/parent/file2');
        createEmptyFile('subdir/parent/file3');
        createEmptyFile('subdir/parent/child/file4');

        // readdirSync lists directory contents, returning an array of strings.
        const c = fs.readdirSync('subdir/parent', { withFileTypes: true });

        console.log('Listing subdir/parent');
        for (const entry of c) {
            console.log(' ', entry.name, entry.isDirectory());
        }

        // process.chdir lets us change the current working directory,
        // similarly to `cd`.
        process.chdir('subdir/parent/child');

        // Now we'll see the contents of `subdir/parent/child`
        // when listing the current directory.
        const c2 = fs.readdirSync('.', { withFileTypes: true });

        console.log('Listing subdir/parent/child');
        for (const entry of c2) {
            console.log(' ', entry.name, entry.isDirectory());
        }

        // Change back to where we started.
        process.chdir('../../..');

        // We can also visit a directory recursively,
        // including all its sub-directories.
        console.log('Visiting subdir');
        visitDir('subdir');
    } finally {
        // Clean up: remove the entire directory tree.
        fs.rmdirSync('subdir', { recursive: true });
    }
}

// visitDir is called for every file or directory found recursively.
function visitDir(dir: string) {
    const entries = fs.readdirSync(dir, { withFileTypes: true });
    for (const entry of entries) {
        const fullPath = path.join(dir, entry.name);
        console.log(' ', fullPath, entry.isDirectory());
        if (entry.isDirectory()) {
            visitDir(fullPath);
        }
    }
}

main();

To run this program, save it as directories.ts and use ts-node (assuming you have it installed):

$ ts-node directories.ts
Listing subdir/parent
  child true
  file2 false
  file3 false
Listing subdir/parent/child
  file4 false
Visiting subdir
  subdir true
  subdir/file1 false
  subdir/parent true
  subdir/parent/child true
  subdir/parent/child/file4 false
  subdir/parent/file2 false
  subdir/parent/file3 false

This TypeScript code demonstrates various operations on directories, including creating directories, listing contents, changing the current working directory, and recursively visiting a directory tree. It uses the fs module for file system operations and the path module for working with file paths.

Note that in TypeScript (and Node.js), some operations that were synchronous in the Go example are typically performed asynchronously. However, for simplicity and to maintain a similar structure to the original example, we’ve used the synchronous versions of these functions (like mkdirSync, writeFileSync, etc.). In a real-world application, you might prefer to use the asynchronous versions of these functions for better performance and to avoid blocking the event loop.