MQ
QURASHI
Blog
MQ
MOHAMED QURASHI

© 2026 Mohamed Qurashi. All rights reserved.

Built with precisionDesigned for impactPowered by innovation
MQ
QURASHI
Blog
Back to Blog
Web Development

Mastering TypeScript: Advanced Patterns

Mohamed Qurashi
November 28, 2024
20 min read
Mastering TypeScript: Advanced Patterns

Share

TwitterFacebookLinkedIn

Tags

TypeScriptProgrammingWeb Development

TypeScript adds powerful type safety to JavaScript, enabling you to build more robust and maintainable applications. This guide explores advanced TypeScript patterns and best practices.


Advanced Type Features


Conditional Types

Create types that depend on other types:

type NonNullable<T> = T extends null | undefined ? never : T;


type ApiResponse<T> = T extends string

? { message: T }

: { data: T };


Mapped Types

Transform existing types:

type Readonly<T> = {

readonly [P in keyof T]: T[P];

};


type Optional<T> = {

[P in keyof T]?: T[P];

};


Template Literal Types

Create types from string templates:

type EventName<T extends string> = `on${Capitalize<T>}`;


type ClickEvent = EventName<'click'>; // 'onClick'


Generics Deep Dive


Generic Constraints

interface Lengthwise {

length: number;

}


function logLength<T extends Lengthwise>(arg: T): T {

console.log(arg.length);

return arg;

}


Generic Utility Types

// Partial: Make all properties optional

type PartialUser = Partial<User>;


// Pick: Select specific properties

type UserEmail = Pick<User, 'email'>;


// Omit: Exclude specific properties

type UserWithoutId = Omit<User, 'id'>;


// Record: Create object type

type UserRoles = Record<string, boolean>;


Design Patterns


Factory Pattern

interface Product {

name: string;

price: number;

}


class ProductFactory {

static create<T extends Product>(type: new () => T): T {

return new type();

}

}


Builder Pattern

class QueryBuilder {

private query: string = '';


select(fields: string): this {

this.query += `SELECT ${fields}`;

return this;

}


from(table: string): this {

this.query += ` FROM ${table}`;

return this;

}


build(): string {

return this.query;

}

}


Singleton Pattern

class Database {

private static instance: Database;


private constructor() {}


static getInstance(): Database {

if (!Database.instance) {

Database.instance = new Database();

}

return Database.instance;

}

}


Advanced Utility Types


Extract and Exclude

type T0 = Extract<'a' | 'b' | 'c', 'a' | 'f'>; // 'a'

type T1 = Exclude<'a' | 'b' | 'c', 'a'>; // 'b' | 'c'


ReturnType and Parameters

function getUser(id: number): User {

return { id, name: 'John' };

}


type UserReturn = ReturnType<typeof getUser>; // User

type UserParams = Parameters<typeof getUser>; // [number]


Type Guards


User-Defined Type Guards

function isString(value: unknown): value is string {

return typeof value === 'string';

}


function processValue(value: unknown) {

if (isString(value)) {

// TypeScript knows value is string here

console.log(value.toUpperCase());

}

}


Decorators (Experimental)


function Log(target: any, propertyKey: string, descriptor: PropertyDescriptor) {

const original = descriptor.value;

descriptor.value = function (...args: any[]) {

console.log(`Calling ${propertyKey}`);

return original.apply(this, args);

};

}


class Calculator {

@Log

add(a: number, b: number): number {

return a + b;

}

}


Best Practices


1. Use Strict Mode

Enable strict type checking in tsconfig.json:

{

"compilerOptions": {

"strict": true,

"noImplicitAny": true,

"strictNullChecks": true

}

}


2. Avoid Any

Use `unknown` instead of `any` when type is truly unknown:

function process(data: unknown) {

if (typeof data === 'string') {

// Type narrowing works

}

}


3. Use Interfaces for Objects

Use interfaces for object shapes, types for unions/intersections:

interface User {

id: number;

name: string;

}


type Status = 'active' | 'inactive';


4. Leverage Type Inference

Let TypeScript infer types when possible:

const users = ['John', 'Jane']; // string[]

const count = 42; // number


Mastering these advanced TypeScript patterns will help you write more type-safe, maintainable code. Practice with real projects and gradually incorporate these patterns into your workflow.

Related Articles

React vs Vue: A Comprehensive Comparison for 2024
Web Development

React vs Vue: A Comprehensive Comparison for 2024

A detailed comparison between the most popular frontend frameworks with practical examples and tips for choosing.