TypeScript for Beginners
TypeScript adds static typing to JavaScript, catching errors at compile time instead of at runtime. If you know JavaScript, you already know most of TypeScript. This guide covers the essentials to get you productive quickly.
Why TypeScript?
Consider this JavaScript code:
// JavaScript - no type safety
function greet(name) {
return "Hello, " + name.toUpperCase();
}
greet(123); // No error in JS, crashes at runtime
greet(null); // Also crashes
The same code in TypeScript:
// TypeScript - catches errors before running
function greet(name: string): string {
return `Hello, ${name.toUpperCase()}`;
}
greet(123); // Error: Argument of type 'number' is not assignable to parameter of type 'string'
TypeScript catches bugs during development, improves IDE autocomplete, and serves as living documentation for your codebase.
Basic Types
TypeScript supports all the types you'd expect:
// Primitive types
let username: string = "devuser";
let age: number = 28;
let isActive: boolean = true;
let nothing: null = null;
let notSet: undefined = undefined;
let id: symbol = Symbol("id");
// Arrays
let scores: number[] = [95, 87, 92];
let names: Array<string> = ["Alice", "Bob"];
// Tuples (fixed-length arrays with known types)
let user: [string, number] = ["Alice", 28];
// Enums
enum Role {
Admin = "admin",
User = "user",
Guest = "guest",
}
let currentRole: Role = Role.Admin;
Interfaces and Types
Define the shape of objects with interfaces:
interface User {
id: number;
name: string;
email: string;
role?: Role; // Optional property
}
function displayUser(user: User) {
console.log(`${user.name} (${user.email})`);
}
// Type aliases for unions and intersections
type ID = string | number;
type AdminUser = User & {
permissions: string[];
};
Functions with Types
TypeScript infers types in many cases, but explicit types improve clarity:
// Explicit return type
function add(a: number, b: number): number {
return a + b;
}
// Optional parameters with defaults
function greet(name: string, greeting: string = "Hello"): string {
return `${greeting}, ${name}!`;
}
// Void for functions that don't return a value
function log(message: string): void {
console.log(message);
}
// Union types for functions accepting multiple kinds of input
function formatValue(value: string | number): string {
return String(value).trim();
}
Generics
Generics let you write reusable, type-safe functions and components:
// A generic function that returns the first element
function first<T>(array: T[]): T | undefined {
return array[0];
}
const result = first([1, 2, 3]); // T is inferred as number
const name = first(["Alice", "Bob"]); // T is inferred as string
// Generic constraints
interface HasId {
id: number;
}
function getEntityById<T extends HasId>(entities: T[], id: number): T | undefined {
return entities.find(e => e.id === id);
}
Setting Up
Getting started is simple:
# Install TypeScript
npm install --save-dev typescript
# Initialize configuration
npx tsc --init
# Compile your code
npx tsc
# Watch for changes
npx tsc --watch
A minimal tsconfig.json:
{
"compilerOptions": {
"target": "ES2020",
"module": "ESNext",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"outDir": "./dist"
},
"include": ["src/**/*.ts"]
}
Conclusion
TypeScript's learning curve is gentle if you already know JavaScript. Start by adding types to your functions and interfaces, then gradually explore advanced features like generics and utility types. The key is to be consistent — a project with partial types provides little benefit. Use the strict flag from the start, and let TypeScript guide you toward safer, more maintainable code. The time invested in typing pays off immediately through fewer runtime errors and better IDE support.