TypeScript Basics: Type-Safe JavaScript Development
On this page
On this page
TypeScript is a typed superset of JavaScript that compiles to plain JavaScript. It adds static type checking, making your code more robust, maintainable, and easier to refactor. This guide covers TypeScript fundamentals with practical examples for beginners.
What is TypeScript?
TypeScript is developed by Microsoft and extends JavaScript by adding:
- Static typing: Catch errors at compile time, not runtime
- Type inference: Automatically determines types when possible
- Enhanced IDE support: Better autocomplete, refactoring, and navigation
- Modern JavaScript features: Use latest ES features with older browser support
TypeScript code compiles to JavaScript, so it runs anywhere JavaScript runs (browsers, Node.js, etc.).
Installing TypeScript
Install TypeScript:
# Install globally
npm install -g typescript
# Or install locally in your project
npm install --save-dev typescript
# Check version
tsc --version
# Compile TypeScript file
tsc filename.ts
# Initialize TypeScript config
tsc --initRecommended: Use ts-node for running TypeScript directly: npm install -g ts-node
Basic Types
TypeScript basic types:
// Primitive types
let name: string = "TypeScript";
let age: number = 25;
let isActive: boolean = true;
let data: null = null;
let value: undefined = undefined;
// Arrays
let numbers: number[] = [1, 2, 3, 4, 5];
let names: Array<string> = ["John", "Jane"]; // Alternative syntax
// Tuples (fixed-length arrays with specific types)
let person: [string, number] = ["John", 30];
let coordinates: [number, number] = [10, 20];
// Any (avoid when possible)
let anything: any = "can be anything";
anything = 42;
anything = true;
// Unknown (safer than any)
let userInput: unknown;
userInput = 5;
userInput = "hello";
// Need type checking before using
if (typeof userInput === "string") {
console.log(userInput.toUpperCase());
}
// Void (for functions that don't return)
function logMessage(message: string): void {
console.log(message);
}
// Never (for functions that never return)
function throwError(message: string): never {
throw new Error(message);
}Functions with Types
Typed functions:
// Function with typed parameters and return
function add(a: number, b: number): number {
return a + b;
}
// Optional parameters
function greet(name: string, title?: string): string {
if (title) {
return `Hello, ${title} ${name}!`;
}
return `Hello, ${name}!`;
}
// Default parameters
function createUser(name: string, age: number = 18): object {
return { name, age };
}
// Rest parameters
function sum(...numbers: number[]): number {
return numbers.reduce((total, num) => total + num, 0);
}
// Function types
type MathOperation = (a: number, b: number) => number;
const multiply: MathOperation = (a, b) => a * b;
const divide: MathOperation = (a, b) => a / b;
// Arrow functions
const subtract = (a: number, b: number): number => a - b;
// Async functions
async function fetchData(url: string): Promise<object> {
const response = await fetch(url);
return response.json();
}Interfaces and Types
Defining object shapes:
// Interface
interface User {
name: string;
age: number;
email?: string; // Optional property
readonly id: number; // Read-only property
}
const user: User = {
name: "John",
age: 30,
id: 1
};
// user.id = 2; // Error: Cannot assign to 'id' because it is read-only
// Type alias (alternative to interface)
type Point = {
x: number;
y: number;
};
const point: Point = { x: 10, y: 20 };
// Extending interfaces
interface Animal {
name: string;
}
interface Dog extends Animal {
breed: string;
bark(): void;
}
const myDog: Dog = {
name: "Buddy",
breed: "Golden Retriever",
bark: () => console.log("Woof!")
};
// Intersection types
type Employee = {
name: string;
role: string;
};
type Manager = Employee & {
teamSize: number;
};
const manager: Manager = {
name: "Alice",
role: "Engineering Manager",
teamSize: 5
};Classes
TypeScript classes:
class User {
// Public (default)
name: string;
// Private
private email: string;
// Protected (accessible in subclasses)
protected id: number;
// Readonly
readonly createdAt: Date;
constructor(name: string, email: string, id: number) {
this.name = name;
this.email = email;
this.id = id;
this.createdAt = new Date();
}
// Public method
getEmail(): string {
return this.email;
}
// Private method
private validateEmail(email: string): boolean {
return email.includes("@");
}
}
// Inheritance
class Admin extends User {
private permissions: string[];
constructor(name: string, email: string, id: number, permissions: string[]) {
super(name, email, id);
this.permissions = permissions;
}
hasPermission(permission: string): boolean {
return this.permissions.includes(permission);
}
}
// Abstract classes
abstract class Shape {
abstract calculateArea(): number;
display(): void {
console.log(`Area: ${this.calculateArea()}`);
}
}
class Circle extends Shape {
constructor(private radius: number) {
super();
}
calculateArea(): number {
return Math.PI * this.radius ** 2;
}
}Generics
Generics allow you to create reusable components that work with multiple types:
Using generics:
// Generic function
function identity<T>(arg: T): T {
return arg;
}
let output1 = identity<string>("hello");
let output2 = identity<number>(42);
// Generic interface
interface Box<T> {
value: T;
}
const stringBox: Box<string> = { value: "hello" };
const numberBox: Box<number> = { value: 42 };
// Generic class
class Stack<T> {
private items: T[] = [];
push(item: T): void {
this.items.push(item);
}
pop(): T | undefined {
return this.items.pop();
}
}
const numberStack = new Stack<number>();
numberStack.push(1);
numberStack.push(2);
const stringStack = new Stack<string>();
stringStack.push("hello");Learning Resources
Continue learning TypeScript:
- TypeScript Official Docs: Official TypeScript Handbook
- W3Schools TypeScript: TypeScript tutorial
- FreeCodeCamp: TypeScript articles
Share Your Feedback
Your thoughts help me improve my content.