Python Java C++ HTML CSS Bootstrap JavaScript jQuery AngularJS React Node.js TypeScript Django NumPy Pandas Matplotlib Seaborn Machine Learning Deep Learning Decipher XML

Introduction to TypeScript

TypeScript is a strongly typed superset of JavaScript that compiles to plain JavaScript. It adds a static type system, modern ECMAScript features, and tooling that helps teams build large, reliable applications.

Why TypeScript is valuable:

  • Early error detection at compile time
  • Safer refactoring with IDE support and type-aware navigation
  • Clear contracts via interfaces and types
  • Incremental adoption in existing JavaScript projects
Key features: Static typing, Classes, Interfaces, Generics, Modules, Async/Await support, and robust tooling.

TypeScript Basics

Setup & Compilation

npm install -g typescript
tsc app.ts          # Compile
tsc --watch app.ts  # Auto compile on save
      

For real projects, configure TypeScript with tsconfig.json so the compiler enforces consistent rules across files.

Types

let isDone: boolean = false;
let age: number = 25;
let name: string = "Nafees";
let arr: number[] = [1,2,3];
let tuple: [string, number] = ["RollNo", 101];
let anything: any = "Hello";
      

Prefer unknown over any for safer handling of dynamic values.

Type Inference

let message = "Hello"; // inferred as string
message = 123;         // ❌ Error
      

Type inference reduces verbosity while still providing strong type checks. Use explicit types for public APIs and complex data structures.

Functions in TypeScript

Typed Functions

function add(a: number, b: number): number {
    return a + b;
}

const multiply = (x: number, y: number): number => x * y;
      

Function types can be declared explicitly to enforce parameter and return shapes.

Optional & Default Parameters

function greet(name: string, greeting?: string){
    console.log(`${greeting || "Hello"} ${name}`);
}
greet("Nafees");      // Hello Nafees
greet("Nafees","Hi"); // Hi Nafees
      

Optional parameters must come after required ones. Default values provide safer function calls.

Rest Parameters

function sum(...nums: number[]): number {
    return nums.reduce((a,b)=>a+b, 0);
}
sum(1,2,3,4); // 10
      

Rest parameters are typed arrays and work well with generics for flexible utilities.

Classes & Interfaces

Classes

class Person {
    name: string;
    age: number;

    constructor(name: string, age: number){
        this.name = name;
        this.age = age;
    }

    greet(): void {
        console.log(`Hello ${this.name}, age ${this.age}`);
    }
}

const p = new Person("Nafees",25);
p.greet();
      

TypeScript supports access modifiers (public, private, protected) and readonly properties for stronger encapsulation.

Interfaces

interface Employee {
    id: number;
    name: string;
    salary?: number; // optional
}

function printEmployee(emp: Employee){
    console.log(emp.name);
}

printEmployee({id:1,name:"Ali"});
      

Interfaces describe shapes of objects, function signatures, and class contracts. They are extendable and can be merged across declarations.

Advanced Types

Union & Intersection Types

let value: string | number;
value = "Hello";
value = 100;

interface A { a: number; }
interface B { b: string; }
type C = A & B; // Intersection type
      

Union types allow flexibility while preserving type safety. Intersections combine multiple type requirements.

Enums

enum Color {Red, Green, Blue}
let c: Color = Color.Green;
      

Enums create named constants. Prefer const enum for performance or union literals for smaller bundles.

Generics

function identity(arg: T): T {
    return arg;
}
let output = identity("Hello");

function getArray(items:T[]): T[] {
    return new Array().concat(items);
}
      

Generics provide reusable, type-safe functions and classes without losing type information.

Type Aliases & Literal Types

type ID = number | string;
let userId: ID = 101;

let direction: "up" | "down" | "left" | "right";
direction = "up"; // valid
      

Literal types and aliases help model strict sets of values and improve autocomplete.

Modules & Namespaces

Modules

// math.ts
export function add(a:number,b:number):number { return a+b; }

// app.ts
import { add } from './math';
console.log(add(2,3));
      

Modules are the recommended approach for modern TypeScript projects. They align with bundlers and tree-shaking.

Namespaces

namespace Utility {
    export function log(msg:string){ console.log(msg); }
}
Utility.log("Hello");
      

Namespaces are mostly used for legacy patterns. Prefer modules for scalability.

TypeScript with DOM

let button = document.getElementById("btn") as HTMLButtonElement;
button.addEventListener("click", ()=>{ alert("Button Clicked!"); });

let input = document.querySelector("input") as HTMLInputElement;
console.log(input.value);
      

TypeScript can narrow DOM types with type assertions and guards. Always handle possible null values when querying elements.

const button = document.getElementById("btn");
if (button instanceof HTMLButtonElement) {
  button.disabled = false;
}

Async Programming

Promises

function fetchData(): Promise {
    return new Promise(resolve => {
        setTimeout(()=> resolve("Data received"), 1000);
    });
}
fetchData().then(console.log);
      

Promises model asynchronous results. Use Promise.all for parallel tasks and handle errors with catch.

Async/Await

async function getData(){
    const result = await fetchData();
    console.log(result);
}
getData();
      

Async/await provides cleaner control flow and easier error handling with try/catch.