Skip to main content

📘 TypeScript Complete Interview Notes (Frontend – In Depth)

Table of Contents

  1. What is TypeScript?
  2. TypeScript vs JavaScript
  3. Type System Basics
  4. Type Inference
  5. Any vs Unknown
  6. Void, Never
  7. Arrays & Tuples
  8. Enums
  9. Objects & Type Aliases
  10. Interfaces vs Type
  11. Optional & Readonly Properties
  12. Union Types
  13. Intersection Types
  14. Literal Types
  15. Functions
  16. Function Overloading
  17. Generics
  18. Utility Types
  19. Type Guards
  20. Discriminated Unions
  21. Type Assertions
  22. Index Signatures
  23. Mapped Types
  24. keyof & typeof
  25. Modules & Namespaces
  26. tsconfig.json
  27. TypeScript with React
  28. Common Interview Traps
  29. When NOT to use TypeScript
  30. Senior Engineer Best Practices
  31. One-Line Interview Summary

1. What is TypeScript?

TypeScript is a statically typed superset of JavaScript that compiles to plain JavaScript.

Why TypeScript exists

JavaScript problems at scale:

  • No static type checking
  • Runtime errors instead of compile-time errors
  • Poor IDE autocomplete and refactoring
  • Hard to maintain large codebases

TypeScript solves this by:

  • Adding static typing
  • Catching errors before runtime
  • Improving developer experience
  • Making code self-documenting

Example

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

add(2, "3"); // ❌ Compile-time error

2. TypeScript vs JavaScript

FeatureJavaScriptTypeScript
TypingDynamicStatic
Error detectionRuntimeCompile time
IDE supportLimitedExcellent
RefactoringRiskySafe
ScalePoorExcellent

3. Type System Basics

Primitive Types

let isDone: boolean = false;
let count: number = 10;
let name: string = "Sayan";
let value: null = null;
let data: undefined = undefined;

Why typing matters

Prevents accidental misuse:

let age: number = 25;
age = "twenty"; // ❌

4. Type Inference

TypeScript can infer types automatically.

let count = 10; // inferred as number
count = 20; // OK
count = "30"; // ❌

Interview insight

Explicit types are recommended for function boundaries, not internal variables.


5. Any vs Unknown

any

  • Disables type checking
  • Dangerous
let value: any = 10;
value.toUpperCase(); // No error, runtime crash

unknown

  • Safer alternative to any
let value: unknown = 10;
value.toUpperCase(); // ❌

if (typeof value === "string") {
value.toUpperCase(); // ✅
}

Interview rule

Prefer unknown over any always.


6. Void, Never

void

Function returns nothing

function logMessage(msg: string): void {
console.log(msg);
}

never

Function never completes

function throwError(): never {
throw new Error("Crash");
}

Used for:

  • Infinite loops
  • Exhaustive checks

7. Arrays & Tuples

Arrays

let numbers: number[] = [1, 2, 3];
let names: Array<string> = ["A", "B"];

Tuples

Fixed-length arrays

let user: [number, string] = [1, "Sayan"];

8. Enums

Numeric Enum

enum Status {
Pending,
Approved,
Rejected,
}
enum Status {
Pending = "PENDING",
Approved = "APPROVED",
Rejected = "REJECTED",
}

Why string enums are better

  • Readable
  • Safer during debugging
  • Stable values

9. Objects & Type Aliases

type User = {
id: number;
name: string;
isActive: boolean;
};

Usage:

const user: User = {
id: 1,
name: "Sayan",
isActive: true,
};

10. Interfaces vs Type

Interface

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

Type

type User = {
id: number;
name: string;
};

Key Differences

Featureinterfacetype
Declaration mergingYesNo
Union typesNoYes
Extendextends&
Preferred forObjectsEverything

Interview rule

Use interface for public APIs, type for unions & advanced types.


11. Optional & Readonly Properties

interface User {
id: number;
name?: string;
readonly email: string;
}

12. Union Types

type Status = "loading" | "success" | "error";

function setStatus(status: Status) {}

Real-world usage

  • API states
  • Feature flags
  • Role-based access

13. Intersection Types

type Admin = { role: "admin" };
type User = { name: string };

type AdminUser = Admin & User;

14. Literal Types

let direction: "left" | "right";
direction = "left";

Used heavily in:

  • Redux
  • Component props
  • State machines

15. Functions

Function Types

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

Optional Parameters

function greet(name?: string) {}

Default Parameters

function greet(name = "Guest") {}

16. Function Overloading

function getValue(value: string): string;
function getValue(value: number): number;
function getValue(value: any) {
return value;
}

Used in:

  • Libraries
  • Complex APIs

17. Generics (Very Important)

Basic Generic

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

Generic Constraints

function logLength<T extends { length: number }>(value: T) {
console.log(value.length);
}

React Example

const useState = <T>(initial: T): [T, (v: T) => void] => {};

18. Utility Types (Frequently Asked)

Partial

type UserUpdate = Partial<User>;

Required

type FullUser = Required<User>;

Pick

type UserPreview = Pick<User, "id" | "name">;

Omit

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

Record

type Roles = Record<string, boolean>;

19. Type Guards

function isString(value: unknown): value is string {
return typeof value === "string";
}

Used in:

  • API responses
  • Runtime validation

20. Discriminated Unions

type Shape =
| { kind: "circle"; radius: number }
| { kind: "square"; size: number };

function area(shape: Shape) {
switch (shape.kind) {
case "circle":
return Math.PI * shape.radius ** 2;
case "square":
return shape.size ** 2;
}
}

Interview favorite question


21. Type Assertions

const value = document.getElementById("app") as HTMLDivElement;

Avoid excessive use — it bypasses safety.


22. Index Signatures

interface ErrorMap {
[key: string]: string;
}

Used in:

  • Dynamic objects
  • Error handling

23. Mapped Types

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

Foundation of utility types.


24. keyof & typeof

type UserKeys = keyof User;

const user = { id: 1, name: "A" };
type UserType = typeof user;

25. Modules & Namespaces

ES Modules

export interface User {}
import { User } from "./types";

Namespaces are legacy — avoid.


26. tsconfig.json (Very Important)

Key options:

{
"strict": true,
"noImplicitAny": true,
"strictNullChecks": true,
"baseUrl": "./src",
"paths": {
"@components/*": ["components/*"]
}
}

Interview insight

strict mode should always be enabled in production apps.


27. TypeScript with React

Props Typing

interface ButtonProps {
label: string;
onClick: () => void;
}

Children

interface Props {
children: React.ReactNode;
}

useState

const [count, setCount] = useState<number>(0);

Event Types

const handleClick = (e: React.MouseEvent<HTMLButtonElement>) => {};

28. Common Interview Traps

  • Overusing any
  • Not narrowing unknown
  • Incorrect union handling
  • Missing never exhaustive checks
  • Ignoring strict null checks

29. When NOT to use TypeScript

  • Very small scripts
  • Prototypes with no future
  • Simple static pages

30. Senior Engineer Best Practices

  • Types at boundaries (API, props)
  • Avoid over-engineering types
  • Prefer readability over cleverness
  • Let inference work
  • Keep types close to usage

31. One-Line Interview Summary

TypeScript is about correctness, scalability, and developer confidence, not just types.