JavaScript + Backend Bootcamp
Day 7 : TypeScript Fundamentals
Today we begin TypeScript.
TypeScript builds on JavaScript by adding static type checking. Type annotations are removed during compilation, producing JavaScript that browsers and Node.js can execute. (TypeScript)
TypeScript is heavily used in:
- Node.js
- Express.js
- React
- Large applications
- Production backend systems
- Team-based development
Recommended Reading 📖
Before starting today’s exercises, read:
From JavaScript to TypeScript: How TypeScript Improves Code Quality
This article introduces the transition from JavaScript to TypeScript and explains how type safety improves code quality.
Today’s lesson expands on that foundation with practical TypeScript setup, compiler configuration, functions, arrays, objects, interfaces, type aliases, unions and API typing.
1. What Is TypeScript?
TypeScript is JavaScript with an additional type system.
JavaScript:
let age = 22;age = "Twenty Two";JavaScript allows the value to change from a number to a string.
TypeScript:
let age: number = 22;age = "Twenty Two";TypeScript reports an error:
Type 'string' is not assignable to type 'number'.This helps identify mistakes before running the application.
2. Why Use TypeScript?
TypeScript provides:
- Type safety
- Better autocomplete
- Earlier error detection
- Safer refactoring
- Better code documentation
- More predictable function inputs and outputs
- Easier collaboration in large projects
TypeScript-aware editors can provide property suggestions, navigation, refactoring tools and errors while you write code. (TypeScript)
3. Create a TypeScript Project
Create a project folder:
mkdir typescript-day-7
cd typescript-day-7Initialize the project:
npm init -yInstall TypeScript locally:
npm install --save-dev typescriptCreate a TypeScript configuration:
npx tsc --initCreate:
src/app.tsSuggested structure:
typescript-day-7/
│
├── src/
│ └── app.ts
│
├── package.json
├── package-lock.json
└── tsconfig.json4. Configure tsconfig.json
Use a beginner-friendly configuration:
{
"compilerOptions": {
"target": "ES2022",
"module": "CommonJS",
"rootDir": "./src",
"outDir": "./dist",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true
}
}Important options:
target: JavaScript version generatedmodule: module systemrootDir: TypeScript source directoryoutDir: compiled JavaScript directorystrict: enables strict type-checking rules
The official TypeScript documentation recommends strict checking for new projects; "strict": true activates the strictness options together. (TypeScript)
5. Compile TypeScript
Add this to src/app.ts:
const message: string = "Hello TypeScript";console.log(message);Compile:
npx tscRun the generated JavaScript:
node dist/app.jsOutput:
Hello TypeScriptTypeScript code is compiled into JavaScript because TypeScript type annotations are not directly executed by JavaScript runtimes. (TypeScript)
6. Watch Mode
Instead of compiling manually after every change:
npx tsc --watchTypeScript will watch your files and recompile when they change.
7. Basic Types
String
let username: string = "Ravi";console.log(username);Number
let age: number = 22;console.log(age);Boolean
let isAdmin: boolean = true;console.log(isAdmin);Use lowercase primitive type names such as string, number and boolean, rather than wrapper types like String, Number and Boolean. (TypeScript)
8. Type Inference
TypeScript can often determine a variable’s type automatically.
let city = "Hyderabad";TypeScript infers:
stringThis produces an error:
city = 100;You do not need to write explicit types everywhere.
Get Bhaskar Chowdary’s stories in your inbox
Join Medium for free to get updates from this writer.
Prefer inference when the type is obvious:
const country = "India";
const score = 95;
const isLoggedIn = true;9. Arrays
Array of Strings
const fruits: string[] = [
"Apple",
"Banana",
"Mango"
];console.log(fruits);Array of Numbers
const marks: number[] = [80, 90, 75];console.log(marks);Generic Array Syntax
const cities: Array<string> = [
"Hyderabad",
"Delhi",
"Chennai"
];Both number[] and Array<number> are valid ways to define typed arrays. (TypeScript)
10. Tuples
A tuple is an array with a fixed structure.
let user: [string, number];user = ["Ravi", 22];This produces an error:
user = [22, "Ravi"];Example:
const response: [number, string] = [
200,
"Success"
];console.log(response);Tuples describe arrays with known element positions and types. (TypeScript)
11. Functions in TypeScript
Parameter Types
function add(a: number, b: number) {
return a + b;
}console.log(add(10, 20));This produces an error:
add("10", 20);Return Type
function multiply(
a: number,
b: number
): number {
return a * b;
}String Return Type
function greet(name: string): string {
return `Hello ${name}`;
}console.log(greet("Ravi"));12. Void Return Type
Use void when a function does not return a useful value.
function showMessage(message: string): void {
console.log(message);
}showMessage("Welcome");13. Optional Parameters
Use ? for optional parameters.
function greet(
name: string,
city?: string
): string {
if (city) {
return `Hello ${name} from ${city}`;
}return `Hello ${name}`;
}console.log(greet("Ravi"));
console.log(greet("Ravi", "Hyderabad"));
14. Default Parameters
function welcome(
name: string = "Guest"
): string {
return `Welcome ${name}`;
}console.log(welcome());
console.log(welcome("Ravi"));15. Arrow Functions with Types
const subtract = (
a: number,
b: number
): number => {
return a - b;
};console.log(subtract(10, 5));Short form:
const square = (value: number): number =>
value * value;16. Object Types
const student: {
name: string;
age: number;
passed: boolean;
} = {
name: "Ravi",
age: 22,
passed: true
};console.log(student);17. Optional Object Properties
const user: {
name: string;
email?: string;
} = {
name: "Ravi"
};email is optional.
18. Readonly Properties
const product: {
readonly id: number;
name: string;
} = {
id: 1,
name: "Laptop"
};This produces an error:
product.id = 2;The name property can still be updated:
product.name = "Gaming Laptop";19. Interfaces
Interfaces define the structure of objects.
interface User {
name: string;
age: number;
isAdmin: boolean;
}const user: User = {
name: "Ravi",
age: 22,
isAdmin: false
};console.log(user);
Interfaces are especially useful for:
- User data
- Product data
- API responses
- Database models
- Function parameters
TypeScript uses structural typing, meaning a value is accepted when it has the required shape. (TypeScript)
20. Interface with Optional and Readonly Properties
interface Product {
readonly id: number;
name: string;
price: number;
description?: string;
}const product: Product = {
id: 1,
name: "Keyboard",
price: 1500
};21. Interface with Functions
interface Calculator {
add(a: number, b: number): number;
subtract(a: number, b: number): number;
}const calculator: Calculator = {
add(a, b) {
return a + b;
}, subtract(a, b) {
return a - b;
}
};console.log(calculator.add(5, 3));
22. Type Aliases
A type alias creates a reusable name for a type.
type UserID = string | number;let firstUserId: UserID = 101;
let secondUserId: UserID = "USER-102";Object example:
type Student = {
name: string;
marks: number;
passed: boolean;
};const student: Student = {
name: "Ravi",
marks: 85,
passed: true
};Type aliases can represent objects, unions, primitives and tuples. (TypeScript)
23. Interface vs Type Alias
Use an interface primarily for object structures:
interface User {
name: string;
age: number;
}Use a type alias when creating:
- Union types
- Tuple types
- Primitive aliases
- More complex composed types
type Status = "pending" | "success" | "failed";Interfaces can be reopened and extended, while a type alias cannot be redeclared in the same way. (TypeScript)
24. Union Types
A union allows more than one possible type.
let userId: string | number;userId = 101;
userId = "USER-101";Function example:
function printId(id: string | number): void {
console.log(`ID: ${id}`);
}printId(100);
printId("ABC-100");A union type represents a value that may be one of several specified types. (TypeScript)
25. Literal Types
Literal types restrict values to exact choices.
type UserRole = "admin" | "user" | "editor";let role: UserRole = "admin";This produces an error:
role = "manager";Backend example:
type RequestMethod =
| "GET"
| "POST"
| "PUT"
| "DELETE";26. any
any disables most type checking.
let data: any = "Hello";data = 100;
data = true;
data.notExistingMethod();Avoid any whenever possible because it removes much of TypeScript’s protection. The noImplicitAny strictness option helps detect values that unintentionally become any. (TypeScript)
27. unknown
unknown can hold any value, but it must be checked before use.
let value: unknown = "Hello TypeScript";if (typeof value === "string") {
console.log(value.toUpperCase());
}Prefer unknown over any when receiving uncertain data.
28. Type Narrowing
Type narrowing checks a value before using it.
function formatValue(
value: string | number
): string {
if (typeof value === "string") {
return value.toUpperCase();
}return value.toFixed(2);
}console.log(formatValue("hello"));
console.log(formatValue(25));
29. Type Assertions
A type assertion tells TypeScript that you know a more specific type.
const input = document.querySelector(
"#username"
) as HTMLInputElement;console.log(input.value);Type assertions do not convert data or perform runtime validation; they only affect the compiler. (TypeScript)
Use them carefully.
30. Typing Async Functions
An async function returns a Promise.
async function getMessage(): Promise<string> {
return "Data loaded";
}getMessage().then((message) => {
console.log(message);
});Object example:
interface User {
id: number;
name: string;
}async function getUser(): Promise<User> {
return {
id: 1,
name: "Ravi"
};
}31. Type-Safe API Response
interface ApiUser {
id: number;
name: string;
email: string;
}async function fetchUsers(): Promise<ApiUser[]> {
const response = await fetch(
"https://jsonplaceholder.typicode.com/users"
); if (!response.ok) {
throw new Error(
`Request failed: ${response.status}`
);
} const data: unknown = await response.json(); return data as ApiUser[];
}
Important:
TypeScript types do not automatically validate external API data at runtime. Later, we’ll use a validation library such as Zod before trusting incoming data.
32. Mini Project — Typed Student Result System
interface Student {
readonly id: number;
name: string;
marks: number;
}type Grade = "A" | "B" | "C" | "Fail";function calculateGrade(marks: number): Grade {
if (marks >= 90) {
return "A";
} if (marks >= 70) {
return "B";
} if (marks >= 40) {
return "C";
} return "Fail";
}function printResult(student: Student): void {
const grade = calculateGrade(student.marks); console.log(`
ID: ${student.id}
Name: ${student.name}
Marks: ${student.marks}
Grade: ${grade}
`);
}const student: Student = {
id: 1,
name: "Ravi",
marks: 85
};printResult(student);
This project combines:
- Interfaces
- Function types
- Literal types
- Return types
- Readonly properties
- Conditions
Common Beginner Mistakes
Using wrapper types
Avoid:
let name: String = "Ravi";
let age: Number = 22;Prefer:
let name: string = "Ravi";
let age: number = 22;Using any everywhere
Avoid:
function processData(data: any): any {
return data;
}Prefer meaningful types:
interface User {
id: number;
name: string;
}function processUser(user: User): User {
return user;
}Adding unnecessary annotations
Unnecessary:
const name: string = "Ravi";Type inference is enough:
const name = "Ravi";Explicit types are most valuable for:
- Function parameters
- Return types
- Public APIs
- Complex objects
- Data received from outside the application
Important Concepts Learned Today
✅ TypeScript setup
✅ tsconfig.json
✅ Compilation with tsc
✅ Strict mode
✅ Basic types
✅ Type inference
✅ Arrays
✅ Tuples
✅ Function types
✅ Optional parameters
✅ Default parameters
✅ Object types
✅ Interfaces
✅ Type aliases
✅ Union types
✅ Literal types
✅ any and unknown
✅ Type narrowing
✅ Type assertions
✅ Async TypeScript
✅ Type-safe API structures
Homework
Create:
- Typed calculator
- Student result system
- Product inventory using interfaces
- User-role system using literal types
- Async function returning typed user data
- Convert one previous JavaScript exercise into TypeScript
Practice Challenge
Build a typed order calculator:
Product: Keyboard
Price: 1500
Quantity: 2
Total: 3000Use:
interface- Typed function parameters
- Number return type
- Template literals
Day 8
Advanced TypeScript
We’ll learn:
- Advanced unions
- Intersection types
- Generics
- Generic constraints
- Classes
- Access modifiers
- Inheritance
- Type guards
- Utility types
keyof- Async TypeScript patterns
- Avoiding unsafe types
- TypeScript best practices
Mini Project:
User Management System






