1. What is TypeScript?

You already know JavaScript. TypeScript is JavaScript with types added on top. Every valid JavaScript file is already valid TypeScript — TypeScript just gives you extra tools to catch mistakes before your code runs.

Key Concept
TypeScript is a superset of JavaScript. That means JS is a subset of TS — all JS code works in TS, but TS adds features JS doesn't have.

Who made it and why?

Microsoft created TypeScript in 2012. As JavaScript projects got bigger, developers kept running into bugs that only showed up when the code ran. TypeScript catches those bugs at compile time — before you even run the code.

How does it work?

Browsers don't understand TypeScript. So TypeScript compiles (transpiles) down to plain JavaScript using the tsc compiler.

// Your TypeScript file: app.ts
let name: string = "Darshan";

// After compilation → app.js (plain JavaScript)
var name = "Darshan";

The flow: .ts file → tsc compiler → .js file → browser runs the .js

Why use TypeScript?

BenefitWhat it means
Catches bugs earlyErrors show up while you code, not when users hit them
Better IDE supportAutocomplete, hover info, refactoring — all powered by types
Self-documentingTypes tell other developers what a function expects and returns
Scales betterLarge projects with many developers stay manageable
JavaScript vs TypeScript
JavaScript — bug hides until runtime:
function add(a, b) {
  return a + b;
}
add(5, "10"); // Returns "510" — no error, silent bug!
TypeScript — bug caught at compile time:
function add(a: number, b: number): number {
  return a + b;
}
add(5, "10"); // ERROR: Argument of type 'string' is not assignable to parameter of type 'number'
Exam Tip
Questions often ask: "TypeScript is a ___ of JavaScript." Answer: superset. Also remember: TypeScript compiles to JavaScript, it does NOT replace JavaScript.

2. Installation & Setup

You need Node.js installed first (which gives you npm). Then install TypeScript globally:

# Install TypeScript globally
npm install -g typescript

# Check version
tsc --version

# Compile a TypeScript file
tsc app.ts        // Creates app.js in the same folder

# Compile and watch for changes
tsc app.ts --watch

tsconfig.json — Project Configuration

For real projects, you create a tsconfig.json file that tells TypeScript how to compile your code. Generate one with tsc --init.

{
  "compilerOptions": {
    "target": "ES6",          // Which JS version to compile to
    "module": "commonjs",     // Module system (commonjs, ES6, etc.)
    "strict": true,           // Enable all strict type checks
    "outDir": "./dist",       // Where compiled JS files go
    "rootDir": "./src"        // Where your TS source files are
  }
}
Tip
strict: true enables all strict checks. In exams, remember that strict mode forces you to declare types — no implicit any allowed.

3. Basic Types (Core Topic)

In JavaScript, variables can hold any type and change type anytime. TypeScript lets you lock a variable to a specific type using type annotations.

Syntax: Type Annotations

// JavaScript way — no types
let name = "Darshan";

// TypeScript way — type annotation after the colon
let name: string = "Darshan";
//       ^^^^^^^^ this is the type annotation

All Basic Types

TypeWhat it holdsExample
stringTextlet city: string = "Mumbai";
numberIntegers and decimalslet age: number = 22;
booleantrue or falselet isActive: boolean = true;
anyAnything (disables type checking)let data: any = "hello";
voidNo return value (for functions)function log(): void { }
nullIntentional absence of valuelet x: null = null;
undefinedVariable declared but not assignedlet y: undefined = undefined;
neverFunction that never returnsThrows error or infinite loop

Examples for Each Type

// string
let company: string = "TCS";

// number (integers AND decimals — no separate int/float)
let score: number = 95;
let price: number = 19.99;

// boolean
let isPassed: boolean = true;

// any — opt out of type checking (avoid in real code)
let random: any = 42;
random = "now a string";  // No error — any allows anything
random = true;             // Still no error

// void — function that doesn't return anything
function sayHello(): void {
  console.log("Hello!");
  // no return statement
}

// never — function that NEVER completes normally
function throwError(msg: string): never {
  throw new Error(msg);  // always throws, never returns
}

Type Inference — TypeScript Guesses the Type

You don't always need to write the type. If you assign a value immediately, TypeScript infers the type automatically:

let city = "Mumbai";     // TypeScript infers: string
let age = 22;            // TypeScript infers: number
let done = true;         // TypeScript infers: boolean

city = 100;              // ERROR — city is already inferred as string
Common Mistake
any defeats the purpose of TypeScript. If everything is any, you're just writing JavaScript with extra steps. Use it only when you genuinely don't know the type (like data from a third-party library).
Exam Tip
void vs never: void means the function returns nothing (it finishes, just no value). never means the function literally never finishes — it throws an error or loops forever. This distinction is a common exam question.

4. Arrays and Tuples

Typed Arrays

In JavaScript, an array can hold anything. In TypeScript, you can restrict what goes in:

// Two ways to declare typed arrays — both are identical
let scores: number[] = [90, 85, 78];
let scores: Array<number> = [90, 85, 78];

// String array
let names: string[] = ["Alice", "Bob"];

// Mixed? Use union type
let mixed: (string | number)[] = ["hello", 42];

scores.push("A");  // ERROR — "A" is a string, not a number

Tuples — Fixed-Length, Fixed-Type Arrays

A tuple is an array where each position has a specific type. The length and order are fixed.

// Tuple: first element is string, second is number
let person: [string, number] = ["Darshan", 22];

// Access like normal array
console.log(person[0]);  // "Darshan" (string)
console.log(person[1]);  // 22 (number)

// ERROR — wrong order
let wrong: [string, number] = [22, "Darshan"];  // Type mismatch!

// ERROR — wrong length
let bad: [string, number] = ["only one"];  // Missing second element
Exam Tip
Tuples enforce both order and length. [string, number] is NOT the same as [number, string]. Exams love swapping the order to test you.

5. Enums

Enums let you define a set of named constants. Use them when you have a fixed group of related values (directions, colors, statuses).

Numeric Enums (default)

enum Direction {
  Up,      // 0
  Down,    // 1
  Left,    // 2
  Right    // 3
}

let move: Direction = Direction.Up;
console.log(move);           // 0
console.log(Direction.Right); // 3

By default, the first value is 0 and each subsequent value increments by 1. You can start from a different number:

enum Status {
  Active = 1,    // 1
  Inactive,       // 2 (auto-increments)
  Pending         // 3
}

String Enums

enum Color {
  Red = "RED",
  Green = "GREEN",
  Blue = "BLUE"
}

console.log(Color.Red);  // "RED"
Tip
String enums are more readable in logs and debugging. Numeric enums are default and more common in exam questions. Know both.
Exam Tip
If the exam asks "What is the value of Direction.Left?" — count from 0. Up=0, Down=1, Left=2, Right=3. Unless a starting number is specified.

6. Functions with Types

In JavaScript, functions accept anything and return anything. TypeScript lets you specify parameter types and return types.

Basic Typed Function

// JavaScript
function add(a, b) {
  return a + b;
}

// TypeScript — types for parameters AND return value
function add(a: number, b: number): number {
  return a + b;
}

Optional Parameters

Add ? after the parameter name to make it optional. Optional parameters must come after required ones.

function greet(name: string, greeting?: string): string {
  return (greeting || "Hello") + ", " + name;
}

greet("Darshan");             // "Hello, Darshan"
greet("Darshan", "Hey");     // "Hey, Darshan"

Default Parameters

function greet(name: string = "World"): string {
  return "Hello, " + name;
}

greet();           // "Hello, World"
greet("Darshan"); // "Hello, Darshan"

Arrow Functions with Types

const multiply = (a: number, b: number): number => a * b;

const logMessage = (msg: string): void => {
  console.log(msg);
};
Exam Tip
Optional parameter name?:string means you can call the function without that argument. Default parameter name:string = "X" provides a fallback value. Both make the argument non-mandatory, but they work differently.

7. Interfaces (Very Important)

An interface defines the shape of an object — what properties it must have and their types. Think of it as a contract: any object claiming to be this type must have these properties.

Basic Interface

interface User {
  name: string;
  age: number;
  email: string;
}

// Object must match the shape exactly
let user: User = {
  name: "Darshan",
  age: 22,
  email: "darshan@example.com"
};

// ERROR — missing 'email' property
let badUser: User = {
  name: "Test",
  age: 20
};

Optional Properties

interface User {
  name: string;
  age: number;
  email?: string;   // optional — may or may not exist
}

let user: User = { name: "Darshan", age: 22 };  // OK — email is optional

Readonly Properties

interface User {
  readonly id: number;   // cannot be changed after creation
  name: string;
}

let user: User = { id: 1, name: "Darshan" };
user.name = "New Name";  // OK
user.id = 2;              // ERROR — readonly!

Extending Interfaces

One interface can inherit from another using extends:

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

interface Admin extends User {
  role: string;
}

// Admin must have ALL User properties + role
let admin: Admin = {
  name: "Darshan",
  age: 22,
  role: "superadmin"
};

Interface for Function Types

interface MathFunc {
  (a: number, b: number): number;
}

const add: MathFunc = (a, b) => a + b;
const sub: MathFunc = (a, b) => a - b;

Interface vs Type Alias

Featureinterfacetype
Extend/inheritextends& (intersection)
Declaration mergingYes (same name = merged)No (error if duplicate)
Union typesCannot dotype X = A | B
PrimitivesCannot representtype ID = string
Best forObject shapes, class contractsUnions, aliases, complex types
Key Rule
Use interface for object shapes and class contracts. Use type for unions, intersections, and primitives. In Angular (which you'll learn next), interfaces are used everywhere.
Exam Tip
Declaration merging is a unique interface feature. If you declare the same interface name twice, TypeScript merges them into one. Types throw an error for duplicates. This is asked in exams.

8. Type Aliases

The type keyword creates a custom name for any type — simple or complex.

Basic Type Alias

type StringOrNumber = string | number;

let id: StringOrNumber = 101;     // OK
id = "ABC-101";                     // Also OK
id = true;                           // ERROR — boolean not allowed

Union Types — "this OR that"

type Status = "active" | "inactive" | "pending";

let userStatus: Status = "active";    // OK
userStatus = "banned";                  // ERROR — not in the union

Intersection Types — "this AND that"

type HasName = { name: string };
type HasAge = { age: number };
type Person = HasName & HasAge;  // Must have BOTH name AND age

let p: Person = { name: "Darshan", age: 22 };  // OK

Literal Types — Exact Values Only

type Direction = "up" | "down" | "left" | "right";

let dir: Direction = "up";       // OK
dir = "diagonal";                    // ERROR — not a valid direction
Tip
Union = OR (one of these types). Intersection = AND (all of these types combined). The symbols: | for union, & for intersection.

9. Classes in TypeScript

TypeScript classes are JavaScript classes with access modifiers, type annotations, and shortcuts.

Access Modifiers

ModifierAccessible fromDefault?
publicEverywhereYes (if you don't write anything)
privateOnly inside the same classNo
protectedInside the class + child classesNo
class Employee {
  public name: string;
  private salary: number;
  protected department: string;

  constructor(name: string, salary: number, dept: string) {
    this.name = name;
    this.salary = salary;
    this.department = dept;
  }

  getSalary(): number {
    return this.salary;  // OK — accessing private inside the class
  }
}

let emp = new Employee("Darshan", 50000, "IT");
console.log(emp.name);       // OK — public
console.log(emp.salary);     // ERROR — private, cannot access outside class
console.log(emp.department);  // ERROR — protected, only in class or subclass

Readonly Properties

class User {
  readonly id: number;
  name: string;

  constructor(id: number, name: string) {
    this.id = id;      // OK — can set in constructor
    this.name = name;
  }
}

let u = new User(1, "Darshan");
u.id = 2;  // ERROR — readonly, can only be set in constructor

Constructor Shorthand

TypeScript lets you declare and initialize properties directly in the constructor parameters:

// Long way
class User {
  public name: string;
  private age: number;
  constructor(name: string, age: number) {
    this.name = name;
    this.age = age;
  }
}

// Shorthand — does EXACTLY the same thing
class User {
  constructor(public name: string, private age: number) {}
}
Key Concept
The constructor shorthand only works when you add an access modifier (public, private, protected) or readonly before the parameter. Without a modifier, it's just a regular parameter — not a class property.

Implementing Interfaces

interface IUser {
  name: string;
  greet(): string;
}

class User implements IUser {
  constructor(public name: string) {}

  greet(): string {
    return "Hi, I'm " + this.name;
  }
}
// Class MUST have everything the interface requires

Abstract Classes

Abstract classes are base classes that cannot be instantiated directly. They can have abstract methods (no body — child must implement) and regular methods.

abstract class Shape {
  abstract area(): number;  // no body — child MUST implement

  describe(): string {
    return "I am a shape with area: " + this.area();
  }
}

class Circle extends Shape {
  constructor(private radius: number) { super(); }

  area(): number {
    return Math.PI * this.radius ** 2;
  }
}

// let s = new Shape();    // ERROR — cannot instantiate abstract class
let c = new Circle(5);    // OK
Exam Tip
Access modifier visibility: public = everywhere. protected = class + subclasses. private = class only. If nothing is written, it's public by default. This is asked repeatedly.

10. Generics (Basics)

Generics let you write functions, classes, and interfaces that work with any type while still being type-safe. Think of <T> as a placeholder for "whatever type you give me."

The Problem Generics Solve

// Without generics — works but loses type info
function identity(arg: any): any {
  return arg;
}
let result = identity("hello");  // result is 'any', not 'string'

// With generics — type-safe AND flexible
function identity<T>(arg: T): T {
  return arg;
}
let result = identity<string>("hello");  // result is 'string'
let num = identity<number>(42);         // num is 'number'

Generic Interface

interface ApiResponse<T> {
  data: T;
  status: number;
  message: string;
}

let userResponse: ApiResponse<string> = {
  data: "Darshan",
  status: 200,
  message: "OK"
};

let numResponse: ApiResponse<number[]> = {
  data: [1, 2, 3],
  status: 200,
  message: "OK"
};

Generic Class

class Box<T> {
  private content: T;

  constructor(value: T) {
    this.content = value;
  }

  getValue(): T {
    return this.content;
  }
}

let stringBox = new Box<string>("Hello");
let numberBox = new Box<number>(100);
Tip
T is just a convention. You can use any letter: T (Type), K (Key), V (Value), E (Element). The angle brackets <T> declare the generic type parameter.
Exam Tip
When you see function identity<T>(arg: T): T, read it as: "This function takes something of type T and returns the same type T." If called with identity<number>(5), T becomes number, so it returns a number.

11. Type Guards and Narrowing

When a variable can be multiple types (union type), you need to narrow it down to a specific type before using type-specific operations.

typeof Guard

function print(value: string | number) {
  if (typeof value === "string") {
    // TypeScript knows value is a string here
    console.log(value.toUpperCase());
  } else {
    // TypeScript knows value is a number here
    console.log(value.toFixed(2));
  }
}

instanceof Guard

class Dog { bark() { return "Woof!"; } }
class Cat { meow() { return "Meow!"; } }

function speak(pet: Dog | Cat) {
  if (pet instanceof Dog) {
    console.log(pet.bark());
  } else {
    console.log(pet.meow());
  }
}

Type Assertions

When you know the type better than TypeScript does, use assertions to tell it:

// Two syntaxes — both do the same thing
let value: any = "hello";

// Syntax 1: as keyword (preferred)
let length: number = (value as string).length;

// Syntax 2: angle bracket (cannot use in JSX/React)
let length: number = (<string>value).length;

Non-null Assertion

let element = document.getElementById("app");  // type: HTMLElement | null

// Adding ! tells TypeScript: "Trust me, this is NOT null"
let el = document.getElementById("app")!;  // type: HTMLElement
Warning
Type assertions don't do any runtime checking. If you assert value as string but value is actually a number, you'll get a runtime error. Use them only when you're truly sure of the type.

12. Utility Types

TypeScript provides built-in utility types that transform existing types. You don't need to memorize all of them, but know the common ones:

Utility TypeWhat it doesExample
Partial<T>Makes ALL properties optionalPartial<User> — can have some or no User fields
Required<T>Makes ALL properties requiredOpposite of Partial
Readonly<T>Makes ALL properties readonlyCannot modify any property
Pick<T, K>Selects only specified propertiesPick<User, "name" | "age">
Omit<T, K>Removes specified propertiesOmit<User, "password">
Record<K, V>Creates object type with keys K and values VRecord<string, number>
interface User {
  name: string;
  age: number;
  email: string;
}

// Partial — all properties become optional
function updateUser(user: Partial<User>) {
  // Can pass { name: "X" } without age and email
}

// Pick — only selected properties
type UserPreview = Pick<User, "name" | "age">;
// UserPreview = { name: string; age: number; }  (no email)

// Omit — everything except specified
type PublicUser = Omit<User, "email">;
// PublicUser = { name: string; age: number; }  (email removed)

// Record — map of keys to values
type Scores = Record<string, number>;
let marks: Scores = { math: 90, science: 85 };
Exam Tip
Partial makes everything optional, Required makes everything mandatory. Pick keeps the listed properties, Omit removes them. Think: Pick = include list, Omit = exclude list.

13. TypeScript vs JavaScript — Complete Comparison

FeatureJavaScriptTypeScript
Type systemDynamic (types checked at runtime)Static (types checked at compile time)
File extension.js.ts
Type annotationsNot supportedlet x: number = 5;
InterfacesNot availableFully supported
EnumsNot availableFully supported
GenericsNot availableFully supported
Access modifiersNot available (ES2022 has #private)public, private, protected
CompilationInterpreted directly by browserMust compile to JS first (tsc)
Error detectionRuntime onlyCompile time + runtime
ToolingGoodExcellent (autocomplete, refactoring)
Browser supportNativeNot native — compiles to JS
Learning curveLowerHigher (must learn types)
Superset?Yes — all JS is valid TS
Created byBrendan Eich (Netscape, 1995)Microsoft (2012)
Used by Angular?No (AngularJS used JS)Yes — Angular requires TypeScript
Key Takeaway
TypeScript adds compile-time safety, interfaces, enums, generics, and access modifiers — none of which exist in JavaScript. But TypeScript always compiles down to JavaScript in the end. Browsers never run TypeScript directly.

14. Practice Questions

Question 1
TypeScript is a ___ of JavaScript.
  1. Subset
  2. Superset
  3. Replacement
  4. Framework
B) Superset — TypeScript includes all of JavaScript plus additional features like static typing.
Question 2
What is the output of the following code?
enum Fruit { Apple, Banana, Cherry }
console.log(Fruit.Cherry);
  1. "Cherry"
  2. 2
  3. 3
  4. undefined
B) 2 — Numeric enums start at 0 by default. Apple=0, Banana=1, Cherry=2.
Question 3
Which TypeScript type should be used for a function that never returns (always throws an error)?
  1. void
  2. null
  3. never
  4. undefined
C) never — Used for functions that never complete normally (throw errors or infinite loops). void is for functions that complete but return no value.
Question 4
What is wrong with this code?
interface Car {
  readonly brand: string;
  model: string;
}
let car: Car = { brand: "Toyota", model: "Camry" };
car.brand = "Honda";
  1. Cannot use readonly with interfaces
  2. brand is readonly and cannot be reassigned
  3. model should also be readonly
  4. No error — this is valid
B) brand is readonly and cannot be reassigned — Once a readonly property is set, it cannot be changed.
Question 5
What is the correct syntax for a tuple that holds a string and a number?
  1. let t: (string | number) = ["hi", 5];
  2. let t: [string, number] = ["hi", 5];
  3. let t: string | number[] = ["hi", 5];
  4. let t: Array<string, number> = ["hi", 5];
B) [string, number] — Tuples use square brackets with the types in order. This is different from a union array.
Question 6
What does the ? mean in this interface?
interface Product {
  name: string;
  price: number;
  description?: string;
}
  1. description must be null
  2. description is optional — may or may not be present
  3. description is nullable
  4. description has a default value
B) description is optional — The ? after a property name makes it optional. The object can be created with or without it.
Question 7
Which access modifier allows access from the class itself AND its subclasses, but NOT from outside?
  1. public
  2. private
  3. protected
  4. readonly
C) protected — public = everywhere, private = same class only, protected = same class + child classes.
Question 8
What is the output type of this function?
function identity<T>(arg: T): T { return arg; }
let result = identity<number>(42);
  1. any
  2. string
  3. number
  4. T
C) number — When called with <number>, the generic T becomes number. So the function takes a number and returns a number.
Question 9
Which of the following is NOT a valid TypeScript basic type?
  1. string
  2. float
  3. boolean
  4. never
B) float — TypeScript has number for all numeric values (both integers and decimals). There is no separate float or int type.
Question 10
What does Partial<User> do?
  1. Makes all properties of User readonly
  2. Makes all properties of User required
  3. Makes all properties of User optional
  4. Removes all properties from User
C) Makes all properties of User optional — Partial<T> converts every property in T to optional (adds ? to each one).
Question 11
What is the difference between interface and type in TypeScript?
  1. They are completely identical
  2. Interfaces support declaration merging; types do not
  3. Types support extends; interfaces do not
  4. Interfaces can represent union types; types cannot
B) Interfaces support declaration merging; types do not — If you declare the same interface name twice, TypeScript merges them. Duplicate type names cause an error. Also, only types support union (|) syntax.
Question 12
What does this TypeScript code produce?
let x: string | number = "hello";
x = 42;
x = true;
  1. No error — all types are allowed
  2. Error at x = 42
  3. Error at x = true
  4. Error at the declaration
C) Error at x = true — The union type string | number allows only strings and numbers. boolean is not in the union, so true causes a compile error.
Question 13
What does the constructor shorthand do in this code?
class Person {
  constructor(public name: string, private age: number) {}
}
  1. Creates local variables inside the constructor only
  2. Automatically creates class properties and assigns them
  3. Makes the class abstract
  4. This syntax is invalid
B) Automatically creates class properties and assigns them — Adding an access modifier (public, private, protected) in the constructor parameter automatically declares the property, creates it, and assigns the value. It's a shorthand.
Question 14
Which command compiles a TypeScript file to JavaScript?
  1. node app.ts
  2. ts app.ts
  3. tsc app.ts
  4. npm run ts app.ts
C) tsc app.ts — The TypeScript compiler command is tsc. It compiles .ts files into .js files.
Question 15
What does extends do in this interface?
interface Animal { name: string; }
interface Dog extends Animal { breed: string; }
  1. Dog replaces Animal
  2. Dog inherits all properties from Animal and adds its own
  3. Dog can only access breed, not name
  4. This syntax is not valid for interfaces
B) Dog inherits all properties from Animal and adds its own — extends means Dog has everything Animal has (name: string) PLUS its own properties (breed: string). Any object typed as Dog must have both.
Question 16
What is the default access modifier for class members in TypeScript?
  1. private
  2. protected
  3. public
  4. readonly
C) public — If you don't write any access modifier, the member is public by default. This means it can be accessed from anywhere.
Question 17
Which utility type creates an object type with keys of type K and values of type V?
  1. Pick<K, V>
  2. Map<K, V>
  3. Record<K, V>
  4. Partial<K, V>
C) Record<K, V> — Creates a type where all keys are of type K and all values are of type V. Example: Record<string, number> means an object with string keys and number values.