Part 6: TypeScript & Node.js - Event Loops and Server-Side Mastery

Master TypeScript type system, Express/Fastify, streams, EventEmitter, worker threads, and NestJS fundamentals for modern server-side development.

Part 6: TypeScript & Node.js - Event Loops and Server-Side Mastery

← Back to Master Index


1. Why TypeScript for Backend in 2026?

TypeScript has become the de facto standard for backend development. It provides:

  • Type safety - Catch bugs at compile time
  • Better IDE support - Autocompletion and refactoring
  • Team collaboration - Clear contracts between services
  • Maintainability - Easier to understand and modify code

Salary Impact

Backend engineers with TypeScript expertise command 10-20% higher salaries than JavaScript-only developers.


2. TypeScript Fundamentals

Basic Types

// Primitive types
let name: string = "John";
let age: number = 30;
let isActive: boolean = true;

// Arrays
let numbers: number[] = [1, 2, 3];
let names: Array<string> = ["Alice", "Bob"];

// Tuples
let tuple: [string, number] = ["age", 30];

// Enums
enum Direction {
    Up = "UP",
    Down = "DOWN",
    Left = "LEFT",
    Right = "RIGHT"
}

// Any and Unknown
let anything: any = "hello";
let unknownType: unknown = "hello";
if (typeof unknownType === "string") {
    let str: string = unknownType;
}

Interfaces and Types

interface User {
    id: number;
    name: string;
    email?: string;  // Optional
    createdAt: Date;
}

type UserResponse = {
    user: User;
    token: string;
};

// Intersection types
type AdminUser = User & { role: "admin" };

// Union types
type Status = "active" | "inactive" | "pending";

Functions

// Function types
function greet(name: string): string {
    return `Hello, ${name}`;
}

// Arrow functions with types
const add = (a: number, b: number): number => a + b;

// Optional and rest parameters
function log(message: string, ...args: unknown[]): void {
    console.log(message, ...args);
}

3. Advanced TypeScript Features

Generics

function identity<T>(arg: T): T {
    return arg;
}

interface Repository<T> {
    findAll(): Promise<T[]>;
    findById(id: number): Promise<T | null>;
}

class UserRepository implements Repository<User> {
    async findAll(): Promise<User[]> {
        return [];
    }
    
    async findById(id: number): Promise<User | null> {
        return null;
    }
}

Decorators

// Class decorators
function singleton(target: Function) {
    let instance: any;
    return function(...args: any[]) {
        if (!instance) {
            instance = new target(...args);
        }
        return instance;
    };
}

@singleton
class DatabaseConnection {
    // Implementation
}

// Method decorators
function logMethod(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
    const originalMethod = descriptor.value;
    descriptor.value = function(...args: any[]) {
        console.log(`Calling ${propertyKey} with`, args);
        return originalMethod.apply(this, args);
    };
}

Advanced Types

// Conditional types
type IsString<T> = T extends string ? true : false;

// Mapped types
type ReadonlyUser = { readonly [K in keyof User]: User[K] };

// Template literal types
type EventName = `on${Capitalize<string>}Change`;

// Utility types
type PartialUser = Partial<User>;
type RequiredEmail = Required<User>;
type UserKeys = keyof User;

4. Node.js Event Loop Deep Dive

Event Loop Phases

// Understanding the event loop
setImmediate(() => console.log('immediate 1'));
process.nextTick(() => console.log('next tick 1'));
setTimeout(() => console.log('timeout 1'), 0);

// Output order:
// next tick 1
// timeout 1
// immediate 1

Event Emitter

const EventEmitter = require('events');

class OrderService extends EventEmitter {
    async processOrder(orderId) {
        // Process order
        this.emit('order.processed', { orderId, status: 'completed' });
    }
}

const service = new OrderService();
service.on('order.processed', (data) => {
    console.log('Order processed:', data);
});

Streams

const fs = require('fs');
const { pipeline } = require('stream');

// Readable stream
const readStream = fs.createReadStream('input.txt');

// Writable stream
const writeStream = fs.createWriteStream('output.txt');

// Pipeline for efficient processing
pipeline(
    readStream,
    transformStream,
    writeStream,
    (err) => {
        if (err) console.error('Pipeline error:', err);
    }
);

5. Building APIs with Express and Fastify

Express.js


const app = express();

// Middleware
app.use(helmet());
app.use(cors());
app.use(express.json());

// Routes
app.get('/api/users', async (req: Request, res: Response) => {
    try {
        const users = await UserService.findAll();
        res.json(users);
    } catch (error) {
        res.status(500).json({ error: 'Internal server error' });
    }
});

// Error handling middleware
app.use((err: Error, req: Request, res: Response, next: NextFunction) => {
    console.error(err.stack);
    res.status(500).json({ error: 'Something went wrong!' });
});

Fastify


const fastify = Fastify({ logger: true });

// Register routes
fastify.get('/api/users/:id', async (request, reply) => {
    const { id } = request.params;
    const user = await UserService.findById(Number(id));
    
    if (!user) {
        return reply.code(404).send({ error: 'User not found' });
    }
    
    return user;
});

// Plugin system
fastify.register(async (fastify) => {
    fastify.get('/health', async () => ({ status: 'ok' }));
});

6. Worker Threads and Clustering

Worker Threads

const { Worker, isMainThread, parentPort, workerData } = require('worker_threads');

if (isMainThread) {
    // Main thread
    const worker = new Worker(__filename, {
        workerData: { numbers: [1, 2, 3, 4, 5] }
    });
    
    worker.on('message', (result) => {
        console.log('Result:', result);
    });
} else {
    // Worker thread
    const { numbers } = workerData;
    const result = numbers.reduce((sum, num) => sum + num, 0);
    parentPort.postMessage(result);
}

Clustering

const cluster = require('cluster');
const numCPUs = require('os').cpus().length;

if (cluster.isMaster) {
    for (let i = 0; i < numCPUs; i++) {
        cluster.fork();
    }
    
    cluster.on('exit', (worker) => {
        console.log(`Worker ${worker.process.pid} died`);
        cluster.fork(); // Restart worker
    });
} else {
    // Start server
    app.listen(3000);
}

7. NestJS Framework

Basic NestJS Application

// main.ts

async function bootstrap() {
    const app = await NestFactory.create(AppModule);
    await app.listen(3000);
}
bootstrap();

// app.module.ts

@Module({
    controllers: [UsersController],
    providers: [UsersService],
})
export class AppModule {}

// users.controller.ts

@Controller('users')
export class UsersController {
    constructor(private readonly usersService: UsersService) {}
    
    @Get()
    findAll() {
        return this.usersService.findAll();
    }
    
    @Post()
    create(@Body() createUserDto: CreateUserDto) {
        return this.usersService.create(createUserDto);
    }
}

8. Resource Directory: TypeScript & Node.js

Best Books

BookAuthorPriceKey Topics
Effective TypeScriptDan VanderkamPaid62 specific ways to use TypeScript
Learning Node.jsO'ReillyPaidNode.js fundamentals
Node.js Design PatternsMario CasciaroPaidAdvanced patterns
Practical Modern JavaScriptNicolas BevacquaPaidES6+ patterns

Best Udemy Courses

CourseInstructorPrice (INR)Key Topics
TypeScript & NodeJSAndrei Neagoie₹399-799TypeScript, Node.js
The Complete Node.js CourseRob Percival₹399-799Express, MongoDB
TypeScript MasterclassMaximilian Schwarzmüller₹399-799Advanced TypeScript
NestJS - The Complete GuideAngela Yu₹399-799NestJS, microservices

Best O'Reilly Resources

ResourceTopicAccess
Learning TypeScriptO'ReillyPaid
Node.js in ActionMike CantelonPaid
Building APIs with Node.jsO'ReillyPaid

Best LinkedIn Learning Courses

CourseInstructorAccess
TypeScript Essential TrainingErin AllardPaid
Node.js Essential TrainingEmetrano SotoPaid
Building RESTful APIsBarron StonePaid

Free Resources

PlatformResourceLink
TypeScript DocsOfficial documentationdocs.microsoft.com/typescript
Node.js DocsOfficial documentationnodejs.org/docs
Express.js GuideOfficial guideexpressjs.com
NestJS DocsOfficial documentationdocs.nestjs.com

9. Common Node.js Interview Questions

QuestionAnswer
Event Loop phases?Timers, Pending callbacks, Idle, Prepare, Poll, Check, Close callbacks
Difference between process.nextTick() and setImmediate()?nextTick runs before event loop continues, setImmediate runs in Check phase
How to handle async errors?Use try/catch in async functions or error handling middleware
What are streams?Objects for working with streaming data (Readable, Writable, Duplex, Transform)
Difference between require and import?require is CommonJS, import is ES6 modules

10. Part Navigation

Previous Parts

Part 5: Async Python & FastAPI

Next Parts

Part 7: PostgreSQL Mastery · Part 8: MongoDB Deep Dive


Proceed to Part 7: PostgreSQL Mastery →

Comments

Comments are powered by giscus. Set PUBLIC_GISCUS_REPO_ID and PUBLIC_GISCUS_CATEGORY_ID in your environment to enable them.