TypeScript: Mastering Static Typing
Learn TypeScript and make your JavaScript code safer and more robust
TypeScript: Mastering Static Typing
TypeScript is a typed superset of JavaScript that compiles to plain JavaScript. Developed by Microsoft and released in 2012, it adds optional static typing and advanced object-oriented features to JavaScript, making large-scale application development safer and more productive.
Note: TypeScript is built on JavaScript. If you need to review the fundamentals, check out our Complete JavaScript Guide before continuing.
Why TypeScript?
TypeScript offers significant benefits for teams and projects of any size:
- Compile-Time Error Detection - Find bugs before running the code
- Enhanced IntelliSense - Smart autocomplete and inline documentation
- Safe Refactoring - Rename variables and functions with confidence
- Implicit Documentation - Types serve as living documentation
- Scalability - Keep large projects organized and safe
- Gradual Adoption - Migrate from JavaScript incrementally
Basic Types
Primitive Types
// Simple types
let name: string = "Maria";
let age: number = 25;
let active: boolean = true;
let nullValue: null = null;
let undefinedValue: undefined = undefined;
// Arrays
let numbers: number[] = [1, 2, 3, 4, 5];
let names: Array<string> = ["Ana", "Pedro", "Carlos"];
// Tuples
let coordinate: [number, number] = [10, 20];
let record: [string, number, boolean] = ["Maria", 25, true];
// Enum
enum Status {
Pending = "PENDING",
Approved = "APPROVED",
Rejected = "REJECTED"
}
let orderStatus: Status = Status.Pending;
Advanced Types
// Union Types
type ID = string | number;
let userId: ID = "abc123";
userId = 42; // Also valid
// Intersection Types
type Person = { name: string };
type Employee = { role: string };
type PersonEmployee = Person & Employee;
// Literal Types
type Direction = "north" | "south" | "east" | "west";
let direction: Direction = "north";
// Template Literal Types
type EventName = `on${Capitalize<string>}`;
// Nullable Types
let optionalValue: string | null = null;
optionalValue = "Defined value";
Interfaces vs Types
// Interface - ideal for objects and classes
interface User {
id: number;
name: string;
email: string;
readonly createdAt: Date;
address?: Address; // Optional property
}
interface Address {
street: string;
city: string;
country: string;
}
// Interface extension
interface Admin extends User {
permissions: string[];
level: "junior" | "senior" | "master";
}
// Type alias - more flexible
type Result<T> =
| { success: true; data: T }
| { success: false; error: string };
type Callback<T> = (data: T) => void;
Generics
// Generic function
function first<T>(array: T[]): T | undefined {
return array[0];
}
const firstNumber = first([1, 2, 3]); // number
const firstString = first(["a", "b", "c"]); // string
// Generic class
class Stack<T> {
private items: T[] = [];
push(item: T): void {
this.items.push(item);
}
pop(): T | undefined {
return this.items.pop();
}
peek(): T | undefined {
return this.items[this.items.length - 1];
}
}
// Constraints
interface WithId {
id: number;
}
function findById<T extends WithId>(items: T[], id: number): T | undefined {
return items.find(item => item.id === id);
}
// Utility Types
type ReadonlyUser = Readonly<User>;
type PartialUser = Partial<User>;
type UserWithoutAddress = Omit<User, "address">;
type OnlyNameEmail = Pick<User, "name" | "email">;
Typed Functions
// Function with explicit types
function calculateDiscount(
price: number,
percentage: number
): number {
return price * (1 - percentage / 100);
}
// Typed arrow function
const multiply = (a: number, b: number): number => a * b;
// Function overloading
function process(value: string): string;
function process(value: number): number;
function process(value: string | number): string | number {
if (typeof value === "string") {
return value.toUpperCase();
}
return value * 2;
}
// Type guards
function isString(value: unknown): value is string {
return typeof value === "string";
}
function formatValue(value: unknown): string {
if (isString(value)) {
return value.trim();
}
return String(value);
}
Classes with TypeScript
abstract class Entity {
constructor(
public readonly id: string,
public createdAt: Date = new Date()
) {}
abstract validate(): boolean;
}
class Product extends Entity {
constructor(
id: string,
public name: string,
public price: number,
private _stock: number = 0
) {
super(id);
}
get stock(): number {
return this._stock;
}
set stock(value: number) {
if (value < 0) {
throw new Error("Stock cannot be negative");
}
this._stock = value;
}
validate(): boolean {
return this.name.length > 0 && this.price > 0;
}
applyDiscount(percentage: number): number {
return this.price * (1 - percentage / 100);
}
}
// Implementing interfaces
interface Serializable {
toJSON(): string;
}
class Item implements Serializable {
constructor(public name: string) {}
toJSON(): string {
return JSON.stringify({ name: this.name });
}
}
Project Configuration
Recommended tsconfig.json
{
"compilerOptions": {
"target": "ES2022",
"module": "ESNext",
"moduleResolution": "bundler",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"outDir": "./dist",
"rootDir": "./src",
"declaration": true,
"declarationMap": true,
"sourceMap": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist"]
}
Learning Checklist
- Master primitive types and arrays
- Understand interfaces and type aliases
- Learn generics and constraints
- Study utility types (Partial, Readonly, Pick, Omit)
- Practice type guards and narrowing
- Configure projects with tsconfig.json
- Migrate an existing JavaScript project
Common Mistakes to Avoid
Using→ Useanyeverywhereunknownor specific typesIgnoring compilation errors→ Fix all type errorsNot using strict mode→ Always enablestrict: trueDuplicating types→ Use utility types to derive types
Essential Resources
Quote
“TypeScript is JavaScript that scales.” - Anders Hejlsberg, TypeScript creator
TypeScript transforms the way you write JavaScript. Invest time learning its features and your productivity will increase significantly!