DEV Community

Cover image for Becoming a TypeScript Pro – Part 3: Advanced & Enterprise-Level Features
MUHAMMAD USMAN AWAN
MUHAMMAD USMAN AWAN

Posted on

Becoming a TypeScript Pro – Part 3: Advanced & Enterprise-Level Features

Deep dive into powerful TS features & patterns

You’ve mastered the basics, leveled up through intermediate patterns — now it’s time to unlock the true power of TypeScript. This is where generics bend to your will, decorators make your classes magical, and configs turn projects into well-oiled enterprise machines. Welcome to Advanced TypeScript.

📕 Advanced TypeScript (Pro Level, Enterprise Ready)

🔹 1. Advanced Generics

Variance (Covariant & Contravariant)

Don’t overthink — it’s about whether you can safely substitute one type for another.

type Animal = { name: string };
type Dog = { name: string; bark: () => void };

let dogHandler: (dog: Dog) => void = (dog) => console.log(dog.name);

// Covariance: assigning more general → more specific ❌
let animalHandler: (animal: Animal) => void;
// animalHandler = dogHandler; ❌ not safe
Enter fullscreen mode Exit fullscreen mode

👉 You won’t often write this directly, but knowing it helps when debugging type errors.

Conditional Generics (T extends U ? X : Y)

type IsString<T> = T extends string ? "yes" : "no";

type A = IsString<string>;  // "yes"
type B = IsString<number>;  // "no"
Enter fullscreen mode Exit fullscreen mode

Infer Keyword

Extract types inside generics.

type ReturnType<T> = T extends (...args: any[]) => infer R ? R : never;

function getUser() { return { id: 1, name: "Ali" }; }

type User = ReturnType<typeof getUser>; // { id: number; name: string }
Enter fullscreen mode Exit fullscreen mode

🔹 2. Mapped & Conditional Types

Creating Custom Utility Types

type MyPartial<T> = {
  [K in keyof T]?: T[K];
};

interface User {
  id: number;
  name: string;
}

type PartialUser = MyPartial<User>; 
// { id?: number; name?: string }
Enter fullscreen mode Exit fullscreen mode

keyof and in Operator

interface Person {
  id: number;
  name: string;
}

type Keys = keyof Person; // "id" | "name"

type Flags = {

};
// { id: boolean; name: boolean }
Enter fullscreen mode Exit fullscreen mode

Remapping Keys

type RemoveId<T> = {

};

type WithoutId = RemoveId<{ id: number; name: string }>;
// { name: string }
Enter fullscreen mode Exit fullscreen mode

🔹 3. Advanced Utility Types

type A = "a" | "b" | "c";
type B = "a" | "d";

type Ex1 = Exclude<A, B>; // "b" | "c"
type Ex2 = Extract<A, B>; // "a"

type NonNull = NonNullable<string | null | undefined>; // string

type AsyncData = Promise<string>;
type Resolved = Awaited<AsyncData>; // string
Enter fullscreen mode Exit fullscreen mode

🔹 4. Type Manipulation & Inference

Index Access Types

interface User {
  id: number;
  name: string;
}

type IdType = User["id"]; // number
Enter fullscreen mode Exit fullscreen mode

Lookup Types

type PropType<T, K extends keyof T> = T[K];

type UserName = PropType<User, "name">; // string
Enter fullscreen mode Exit fullscreen mode

Recursive Types

type NestedArray<T> = T | NestedArray<T>[];

let nums: NestedArray<number> = [1, [2, [3, 4]]];
Enter fullscreen mode Exit fullscreen mode

🔹 5. Decorators (Experimental / Angular / NestJS)

Enable in tsconfig.json:

"experimentalDecorators": true
Enter fullscreen mode Exit fullscreen mode

Class Decorator

function Logger(constructor: Function) {
  console.log("Class created:", constructor.name);
}

@Logger
class Car {}
Enter fullscreen mode Exit fullscreen mode

Method Decorator

function LogMethod(target: any, key: string, descriptor: PropertyDescriptor) {
  const original = descriptor.value;
  descriptor.value = function (...args: any[]) {
    console.log(`Calling ${key} with`, args);
    return original.apply(this, args);
  };
}

class Calculator {
  @LogMethod
  add(a: number, b: number) {
    return a + b;
  }
}

new Calculator().add(2, 3);
Enter fullscreen mode Exit fullscreen mode

🔹 6. Declaration Files (.d.ts)

Used to describe external libraries.

// math.d.ts
declare module "my-math" {
  export function add(a: number, b: number): number;
}
Enter fullscreen mode Exit fullscreen mode

Install community ones:

npm install --save-dev @types/lodash

🔹 7. TypeScript with Frameworks

TS + React

type Props = { name: string; age?: number };

const UserCard: React.FC<Props> = ({ name, age }) => (
  <div>{name} {age && `(${age})`}</div>
);
Enter fullscreen mode Exit fullscreen mode

TS + Node/Express

import express, { Request, Response } from "express";

const app = express();

app.get("/", (req: Request, res: Response) => {
  res.send("Hello TS + Node");
});
Enter fullscreen mode Exit fullscreen mode

TS + Next.js

// pages/api/hello.ts
import { NextApiRequest, NextApiResponse } from "next";

export default function handler(req: NextApiRequest, res: NextApiResponse) {
  res.json({ message: "Hello Next.js + TS" });
}
Enter fullscreen mode Exit fullscreen mode

🔹 8. Config Mastery

Inside tsconfig.json:

{
  "compilerOptions": {
    "strict": true,
    "strictNullChecks": true,
    "noImplicitAny": true,
    "incremental": true,
    "moduleResolution": "node",
    "baseUrl": "./src"
  }
}
Enter fullscreen mode Exit fullscreen mode

🔹 9. Performance & Large-Scale Patterns

  • Avoid overly complex types (keep generics simple).
  • Use project references in monorepos (tsconfig.build.json).
  • Split code into modules for maintainability.

🔹 10. TypeScript 5.x+ Features

satisfies Operator

const colors = {
  red: "#f00",
  green: "#0f0",
} satisfies Record<string, string>;

// ensures keys are string → string
Enter fullscreen mode Exit fullscreen mode

Variadic Tuple Types

type Push<T extends any[], V> = [...T, V];
type Test = Push<[1, 2], 3>; // [1, 2, 3]
Enter fullscreen mode Exit fullscreen mode

Stable Decorators (TS 5+)

@sealed
class MyClass {}
Enter fullscreen mode Exit fullscreen mode

using Declarations (Disposable Resources)

class File {
  [Symbol.dispose]() {
    console.log("File closed");
  }
}

using f = new File();
// auto-disposed after scope
Enter fullscreen mode Exit fullscreen mode

Congrats! If you’ve followed along through Beginner, Intermediate, and now Advanced — you’re not just learning TypeScript, you’re mastering it at a level most devs never reach.

From generics sorcery to enterprise-scale configs — you’ve got the skills to write code that’s clean, scalable, and future-proof.

Part 1: Beginner Foundations
Part 2: Intermediate Concepts

Thanks for reading! 🙌
Until next time, 🫡
Usman Awan (your friendly dev 🚀)

Top comments (0)