Getting Started with TypeScript: A Practical Guide

TypeScript has become the standard for building large-scale JavaScript applications. In this comprehensive guide, we'll explore everything you need to know to get started with TypeScript and write better, more maintainable code.
Why TypeScript?#
TypeScript adds static type checking to JavaScript, catching errors before they reach production. But it's more than just types—it's a better developer experience.
TypeScript is JavaScript that scales. It's a strict syntactical superset of JavaScript that adds optional static typing.
— Anders Hejlsberg, TypeScript Creator
Setting Up Your Environment#
First, let's install TypeScript globally:
npm install -g typescript
Create a new project and initialize it:
mkdir my-ts-project
cd my-ts-project
npm init -y
npm install typescript --save-dev
npx tsc --init
This generates a tsconfig.json file with sensible defaults.
Basic Types#
TypeScript provides several built-in types. Let's explore the most common ones:
// Primitive types
const name: string = "Alice";
const age: number = 30;
const isActive: boolean = true;
// Arrays
const numbers: number[] = [1, 2, 3, 4, 5];
const names: Array<string> = ["Alice", "Bob", "Charlie"];
// Tuples - fixed length arrays with specific types
const coordinate: [number, number] = [10, 20];
const record: [string, number, boolean] = ["Alice", 30, true];
Interfaces and Type Aliases#
Interfaces define the shape of objects:
interface User {
id: number;
name: string;
email: string;
age?: number; // Optional property
readonly createdAt: Date; // Cannot be modified after creation
}
// Using the interface
const user: User = {
id: 1,
name: "Alice",
email: "alice@example.com",
createdAt: new Date()
};
Type aliases offer similar functionality with some differences:
type Point = {
x: number;
y: number;
};
// Union types - only possible with type aliases
type Status = "pending" | "approved" | "rejected";
// Intersection types
type Employee = User & {
department: string;
salary: number;
};
Functions with Types#
TypeScript brings type safety to functions:
// Function with typed parameters and return type
function greet(name: string, greeting: string = "Hello"): string {
return `${greeting}, ${name}!`;
}
// Arrow function with types
const add = (a: number, b: number): number => a + b;
// Function with optional parameters
function createUser(name: string, age?: number): User {
return {
id: Math.random(),
name,
email: `${name.toLowerCase()}@example.com`,
age,
createdAt: new Date()
};
}
// Rest parameters
function sum(...numbers: number[]): number {
return numbers.reduce((acc, curr) => acc + curr, 0);
}
Generics#
Generics allow you to write reusable, type-safe code:
// Generic function
function identity<T>(value: T): T {
return value;
}
const str = identity<string>("hello"); // type: string
const num = identity(42); // type: number (inferred)
// Generic interface
interface ApiResponse<T> {
data: T;
status: number;
message: string;
}
// Using generic interface
interface Product {
id: number;
name: string;
price: number;
}
const response: ApiResponse<Product[]> = {
data: [{ id: 1, name: "Widget", price: 9.99 }],
status: 200,
message: "Success"
};
// Generic with constraint
interface HasLength {
length: number;
}
function logLength<T extends HasLength>(item: T): void {
console.log(`Length: ${item.length}`);
}
logLength("hello"); // Works - strings have length
logLength([1, 2, 3]); // Works - arrays have length
// logLength(42); // Error - numbers don't have length
Working with Classes#
TypeScript enhances JavaScript classes with access modifiers and more:
class BankAccount {
// Properties with access modifiers
private balance: number;
public readonly accountNumber: string;
protected owner: string;
constructor(owner: string, initialBalance: number = 0) {
this.accountNumber = this.generateAccountNumber();
this.owner = owner;
this.balance = initialBalance;
}
private generateAccountNumber(): string {
return Math.random().toString(36).substring(2, 15);
}
public deposit(amount: number): void {
if (amount <= 0) {
throw new Error("Deposit amount must be positive");
}
this.balance += amount;
}
public withdraw(amount: number): boolean {
if (amount > this.balance) {
return false;
}
this.balance -= amount;
return true;
}
public getBalance(): number {
return this.balance;
}
}
Utility Types#
TypeScript provides built-in utility types for common transformations:
interface Todo {
title: string;
description: string;
completed: boolean;
createdAt: Date;
}
// Partial - makes all properties optional
type PartialTodo = Partial<Todo>;
// Required - makes all properties required
type RequiredTodo = Required<Todo>;
// Pick - select specific properties
type TodoPreview = Pick<Todo, "title" | "completed">;
// Omit - exclude specific properties
type TodoWithoutDates = Omit<Todo, "createdAt">;
// Readonly - makes all properties readonly
type ReadonlyTodo = Readonly<Todo>;
// Record - create an object type with specific keys
type TodoRecord = Record<string, Todo>;
Error Handling with Types#
Type-safe error handling patterns:
// Result type pattern
type Result<T, E = Error> =
| { success: true; data: T }
| { success: false; error: E };
async function fetchUser(id: number): Promise<Result<User>> {
try {
const response = await fetch(`/api/users/${id}`);
if (!response.ok) {
return {
success: false,
error: new Error(`HTTP ${response.status}`)
};
}
const data = await response.json();
return { success: true, data };
} catch (error) {
return {
success: false,
error: error instanceof Error ? error : new Error(String(error))
};
}
}
// Usage with type narrowing
const result = await fetchUser(1);
if (result.success) {
console.log(result.data.name); // TypeScript knows data is User
} else {
console.error(result.error.message); // TypeScript knows error is Error
}
Next Steps#
Now that you understand the basics, here are some resources to continue your TypeScript journey:
- TypeScript Handbook - Official documentation
- TypeScript Playground - Experiment with TypeScript online
- DefinitelyTyped - Type definitions for JavaScript libraries
TypeScript transforms how you write JavaScript. Start small, gradually add types to your existing projects, and watch your code quality improve dramatically.
Originally published at https://iuriio.com/blog/posts/2026/01/getting-started-with-typescript



