- Published on
TypeScript for JavaScript Developers - The Complete Beginner's Guide
- Authors

- Name
- Sanjeev Sharma
- @webcoderspeed1
Introduction
TypeScript is no longer optional — it's the professional standard for JavaScript development in 2026. It adds static types to JavaScript, catches bugs at compile time, and makes your IDE incredibly powerful with intelligent autocomplete.
If you know JavaScript, this guide will get you up to speed with TypeScript in one sitting.
- What is TypeScript?
- Setup
- Type Annotations
- Arrays and Objects
- Interfaces vs Types
- Union and Intersection Types
- Generics
- Enums
- Type Narrowing
- Utility Types
- Real-World Example
- Conclusion
What is TypeScript?
TypeScript is a superset of JavaScript — all valid JavaScript is valid TypeScript. TypeScript adds type annotations that are checked at compile time, then stripped out when compiled to JavaScript.
JavaScript code → TypeScript adds types → TypeScript compiler checks types → Outputs clean JavaScript
Setup
npm install -g typescript
tsc --init # Creates tsconfig.json
# Or use ts-node for direct execution
npm install -g ts-node
ts-node your-file.ts
Type Annotations
// Variables
let name: string = 'Alice'
let age: number = 30
let isActive: boolean = true
let anything: any = 'can be anything' // avoid this!
// Functions
function greet(name: string): string {
return `Hello, ${name}!`
}
// Arrow functions
const add = (a: number, b: number): number => a + b
Arrays and Objects
// Arrays
const numbers: number[] = [1, 2, 3]
const names: string[] = ['Alice', 'Bob']
const mixed: (string | number)[] = ['hello', 42]
// Objects — using interfaces
interface User {
id: number
name: string
email: string
age?: number // optional property
}
const user: User = {
id: 1,
name: 'Alice',
email: 'alice@example.com',
// age is optional — OK to omit
}
Interfaces vs Types
Both define shapes, but there are differences:
// Interface — preferred for object shapes
interface Animal {
name: string
sound(): string
}
// Type — great for unions and complex types
type Status = 'active' | 'inactive' | 'pending'
type ID = string | number
// Extending interfaces
interface Dog extends Animal {
breed: string
}
// Intersection types
type AdminUser = User & { adminLevel: number }
Union and Intersection Types
// Union — can be one OR the other
type StringOrNumber = string | number
function formatId(id: string | number): string {
return typeof id === 'string' ? id.toUpperCase() : id.toString()
}
// Literal types
type Direction = 'north' | 'south' | 'east' | 'west'
type DiceRoll = 1 | 2 | 3 | 4 | 5 | 6
function move(direction: Direction) {
console.log(`Moving ${direction}`)
}
move('north') // ✅
move('up') // ❌ TypeScript error!
Generics
Generics make components reusable with different types:
// Without generics — not type-safe
function getFirst(arr: any[]): any {
return arr[0]
}
// With generics — type-safe ✅
function getFirst<T>(arr: T[]): T {
return arr[0]
}
const firstNum = getFirst([1, 2, 3]) // Type: number
const firstName = getFirst(['a', 'b']) // Type: string
// Generic interfaces
interface ApiResponse<T> {
data: T
status: number
message: string
}
const userResponse: ApiResponse<User> = {
data: { id: 1, name: 'Alice', email: 'a@b.com' },
status: 200,
message: 'Success',
}
Enums
enum UserRole {
ADMIN = 'admin',
USER = 'user',
MODERATOR = 'moderator',
}
function checkPermissions(role: UserRole) {
if (role === UserRole.ADMIN) {
console.log('Full access')
}
}
checkPermissions(UserRole.ADMIN) // ✅
checkPermissions('admin') // ❌ Error!
Type Narrowing
TypeScript is smart about types in conditionals:
function processInput(input: string | number) {
if (typeof input === 'string') {
// TypeScript knows input is string here
return input.toUpperCase()
} else {
// TypeScript knows input is number here
return input * 2
}
}
// Nullish checks
function getLength(str: string | null | undefined): number {
if (str == null) return 0
return str.length // TypeScript knows str is string here
}
Utility Types
TypeScript ships with powerful built-in utility types:
interface User {
id: number
name: string
email: string
password: string
}
// Partial — all properties optional
type PartialUser = Partial<User>
// Required — all properties required
type RequiredUser = Required<User>
// Pick — select specific properties
type PublicUser = Pick<User, 'id' | 'name' | 'email'>
// Omit — exclude specific properties
type SafeUser = Omit<User, 'password'>
// Record — dictionary type
type UserMap = Record<string, User>
// Readonly — immutable
type ImmutableUser = Readonly<User>
Real-World Example
interface Product {
id: number
name: string
price: number
category: string
inStock: boolean
}
type CreateProductInput = Omit<Product, 'id'>
type UpdateProductInput = Partial<Omit<Product, 'id'>>
class ProductService {
private products: Product[] = []
create(input: CreateProductInput): Product {
const product: Product = {
id: Date.now(),
...input,
}
this.products.push(product)
return product
}
update(id: number, changes: UpdateProductInput): Product | null {
const idx = this.products.findIndex(p => p.id === id)
if (idx === -1) return null
this.products[idx] = { ...this.products[idx], ...changes }
return this.products[idx]
}
getByCategory(category: string): Product[] {
return this.products.filter(p => p.category === category)
}
}
Conclusion
TypeScript makes JavaScript dramatically safer and more maintainable. The initial setup cost pays back tenfold in fewer bugs, better refactoring, and a far superior IDE experience. Start by adding TypeScript to your next project — you'll never want to go back.