TypeScript Cheatsheet
Classes
Use this TypeScript reference while you build software engineering projects, review code for technical interview prep, or polish examples for a software engineer resume.
Class Declaration
class Animal { name: string; age: number; constructor(name: string, age: number) { this.name = name; this.age = age; } speak(): string { return `${this.name} makes a noise.`; } } const a = new Animal("Dog", 3); a.speak(); // "Dog makes a noise."
Access Modifiers
class Person { public name: string; // accessible everywhere (default) protected age: number; // accessible in class + subclasses private ssn: string; // accessible only in this class readonly id: number; // can't be changed after construction constructor(name: string, age: number, ssn: string, id: number) { this.name = name; this.age = age; this.ssn = ssn; this.id = id; } } // Parameter shorthand (declares AND assigns in one step) class Point { constructor( public x: number, public y: number, private label: string = "point" ) {} } const p = new Point(1, 2); p.x; // 1
Private Fields: # vs private
// TypeScript private — compile-time only; accessible via any at runtime class Safe1 { private secret: string = "ts-private"; } // ECMAScript private field (#) — true runtime privacy class Safe2 { #secret: string = "real-private"; getSecret() { return this.#secret; } } const s = new Safe2(); // s.#secret; // SyntaxError at runtime
Readonly Properties
class Config { readonly maxRetries: number; readonly name: string; constructor(name: string, max: number) { this.name = name; this.maxRetries = max; // OK in constructor } } const cfg = new Config("prod", 3); // cfg.maxRetries = 5; // Error: readonly
Inheritance
class Animal { constructor(public name: string) {} move(distance = 0) { console.log(`${this.name} moved ${distance}m`); } } class Dog extends Animal { constructor(name: string, public breed: string) { super(name); // MUST call super() before using `this` } bark() { console.log("Woof!"); } // Override parent method move(distance = 5) { console.log("Dog is running..."); super.move(distance); // call parent implementation } } const d = new Dog("Rex", "Lab"); d.bark(); d.move(10);
Abstract Classes
// Abstract classes can't be instantiated directly abstract class Shape { abstract area(): number; // must be implemented by subclasses abstract perimeter(): number; // abstract method has no body // Concrete method shared by all subclasses describe(): string { return `Area: ${this.area()}, Perimeter: ${this.perimeter()}`; } } class Circle extends Shape { constructor(public radius: number) { super(); } area() { return Math.PI * this.radius ** 2; } perimeter() { return 2 * Math.PI * this.radius; } } class Rectangle extends Shape { constructor(public w: number, public h: number) { super(); } area() { return this.w * this.h; } perimeter() { return 2 * (this.w + this.h); } } // const s = new Shape(); // Error: Cannot instantiate abstract class const c = new Circle(5); c.describe();
Implementing Interfaces
interface Serializable { serialize(): string; deserialize(data: string): this; } interface Printable { print(): void; } // A class can implement multiple interfaces class Document implements Serializable, Printable { constructor(public content: string) {} serialize(): string { return JSON.stringify({ content: this.content }); } deserialize(data: string): this { this.content = JSON.parse(data).content; return this; } print(): void { console.log(this.content); } }
Static Members
class MathUtils { static PI = 3.14159; private static instances = 0; static circle(r: number): number { return MathUtils.PI * r * r; } static getInstance() { return ++MathUtils.instances; } } MathUtils.PI; // 3.14159 MathUtils.circle(5); // 78.53975 MathUtils.getInstance(); // 1 // Static blocks (ES2022 / TS 4.4+) class Config { static readonly DB_URL: string; static { Config.DB_URL = process.env.DB_URL ?? "localhost"; } }
Getters and Setters
class Temperature { private _celsius: number; constructor(celsius: number) { this._celsius = celsius; } get fahrenheit(): number { return this._celsius * 9 / 5 + 32; } get celsius(): number { return this._celsius; } set celsius(val: number) { if (val < -273.15) throw new RangeError("Below absolute zero"); this._celsius = val; } } const t = new Temperature(0); t.celsius; // 0 t.fahrenheit; // 32 t.celsius = 100; t.fahrenheit; // 212
Generic Classes
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]; } get size(): number { return this.items.length; } isEmpty(): boolean { return this.items.length === 0; } } const numStack = new Stack<number>(); numStack.push(1); numStack.push(2); numStack.pop(); // 2 // Constrained generic class class Repository<T extends { id: number }> { private store: Map<number, T> = new Map(); save(entity: T): void { this.store.set(entity.id, entity); } findById(id: number): T | undefined { return this.store.get(id); } findAll(): T[] { return [...this.store.values()]; } }
Class as Type
class Foo { x = 0; bar() { return "bar"; } } // Class name can be used as a type (instance type) let f: Foo = new Foo(); // typeof ClassName = type of the class constructor type FooClass = typeof Foo; const FooCopy: typeof Foo = Foo; // Extract instance type from class constructor type FooInstance = InstanceType<typeof Foo>; // same as Foo // Structural compatibility (TypeScript uses structural typing) class Bar { x = 0; bar() { return "bar"; } } const b: Foo = new Bar(); // OK — same shape
Mixins Pattern
// Mixin: function that takes a class and returns an extended class type Constructor<T = {}> = new (...args: any[]) => T; function Timestamped<Base extends Constructor>(base: Base) { return class extends base { createdAt = new Date(); }; } function Tagged<Base extends Constructor>(base: Base) { return class extends base { tags: string[] = []; addTag(tag: string) { this.tags.push(tag); } }; } class User { constructor(public name: string) {} } const TimestampedTaggedUser = Tagged(Timestamped(User)); const u = new TimestampedTaggedUser("Alice"); u.createdAt; u.addTag("admin"); u.name;
override Keyword (TS 4.3+)
class Base { greet(): string { return "Hello"; } // If a method is removed from Base, overriding it in Derived is an error } class Derived extends Base { override greet(): string { // 'override' is required with noImplicitOverride: true return super.greet() + " World"; } // override nonExistent(): void {} // Error: 'nonExistent' not in Base }
Class Decorators (Stage 3 / TS 5+)
// Decorator function receives the class function sealed(constructor: Function) { Object.seal(constructor); Object.seal(constructor.prototype); } @sealed class BugReport { type = "report"; constructor(public title: string) {} } // Decorator factory (takes arguments) function logged(prefix: string) { return function(target: Function) { console.log(`${prefix}: ${target.name} defined`); }; } @logged("DEBUG") class Service {}
Index Signatures in Classes
class StringMap { [key: string]: string | (() => string); // index signature name: string = ""; getName(): string { return this.name; } } // Dynamic property access const m = new StringMap(); m["foo"] = "bar"; m.name = "test";
Using Classes as Namespaces
// Inner classes / namespaces class Outer { static Inner = class { value = 42; }; } const inner = new Outer.Inner(); inner.value; // 42