TypeScript Cheatsheet
This page is a quick reference for TypeScript patterns that show up constantly in DSA and competitive programming. TypeScript adds static typing to JavaScript, catching errors at compile time. If you're just starting out, don't worry, every snippet here is explained line by line ๐
Type Annotationsโ
Basic Typesโ
Basic type annotations in TypeScript
let num: number = 42; // Number type
let str: string = "hello"; // String type
let bool: boolean = true; // Boolean type
let nothing: null = null; // Null type
let undef: undefined = undefined; // Undefined type
// Type inference (TypeScript infers type automatically)
let x = 5; // x is inferred as number
let y = "text"; // y is inferred as string
Arrays and Tuplesโ
Array and tuple types
let nums: number[] = [1, 2, 3]; // Array of numbers
let strs: Array<string> = ["a", "b"]; // Alternative syntax
// Tuple โ fixed-length array with specific types
let pair: [number, string] = [1, "one"];
let triple: [number, number, number] = [1, 2, 3];
// Array of tuples
let pairs: [number, string][] = [[1, "one"], [2, "two"]];
Objectsโ
Object type annotations
// Inline object type
let point: { x: number; y: number } = { x: 10, y: 20 };
// Optional properties
let user: { name: string; age?: number } = { name: "Alice" }; // age is optional
// Readonly properties
let config: { readonly apiKey: string } = { apiKey: "secret" };
// config.apiKey = "new"; // Error โ cannot modify readonly property
Interfaces and Type Aliasesโ
Interfacesโ
Interface definitions
interface Point {
x: number;
y: number;
}
const p: Point = { x: 5, y: 10 };
// Optional properties
interface User {
name: string;
age?: number; // Optional
readonly id: number; // Readonly
}
// Extending interfaces
interface Shape {
area(): number;
}
interface Circle extends Shape {
radius: number;
}
const circle: Circle = {
radius: 5,
area() {
return Math.PI * this.radius ** 2;
}
};
Type Aliasesโ
Type alias definitions
type ID = number | string; // Union type
type Point = { x: number; y: number };
let userId: ID = 123; // Can be number
userId = "abc"; // Or string
// Function type
type BinaryOp = (a: number, b: number) => number;
const add: BinaryOp = (a, b) => a + b;
const multiply: BinaryOp = (a, b) => a * b;
Interface vs Type Aliasโ
When to use interface vs type
// Use interface for object shapes (can be extended)
interface Animal {
name: string;
}
interface Dog extends Animal {
breed: string;
}
// Use type for unions, intersections, primitives
type Status = "pending" | "success" | "error"; // Union
type Coordinate = [number, number]; // Tuple
type Nullable<T> = T | null; // Generic
Union and Intersection Typesโ
Union Typesโ
Union type examples
// Variable can be one of multiple types
let value: number | string;
value = 42; // Valid
value = "hello"; // Valid
// value = true; // Error
// Array of mixed types
let mixed: (number | string)[] = [1, "two", 3, "four"];
// Function with union parameter
function print(val: number | string): void {
console.log(val);
}
Intersection Typesโ
Intersection type examples
// Combines multiple types
type Person = { name: string };
type Employee = { id: number };
type Worker = Person & Employee; // Must have both name and id
const worker: Worker = {
name: "Alice",
id: 123
};
Type Guardsโ
Narrowing Typesโ
Type guard patterns
function process(val: number | string) {
if (typeof val === "string") {
// TypeScript knows val is string here
console.log(val.toUpperCase());
} else {
// TypeScript knows val is number here
console.log(val.toFixed(2));
}
}
// Array type guard
function sum(arr: number[] | string) {
if (Array.isArray(arr)) {
return arr.reduce((a, b) => a + b, 0);
}
return parseInt(arr);
}
// Null/undefined check
function getLength(s: string | null): number {
if (s === null) return 0;
return s.length; // TypeScript knows s is string here
}
Custom Type Guardsโ
Custom type guard functions
interface Cat {
meow(): void;
}
interface Dog {
bark(): void;
}
// Type predicate
function isCat(animal: Cat | Dog): animal is Cat {
return (animal as Cat).meow !== undefined;
}
function makeSound(animal: Cat | Dog) {
if (isCat(animal)) {
animal.meow(); // TypeScript knows it's Cat
} else {
animal.bark(); // TypeScript knows it's Dog
}
}
Genericsโ
Generic Functionsโ
Generic function examples
// Generic identity function
function identity<T>(arg: T): T {
return arg;
}
let num = identity<number>(42); // Explicit type
let str = identity("hello"); // Type inferred
// Generic with constraints
function getProperty<T, K extends keyof T>(obj: T, key: K): T[K] {
return obj[key];
}
const person = { name: "Alice", age: 30 };
const name = getProperty(person, "name"); // Type is string
const age = getProperty(person, "age"); // Type is number
Generic Interfaces and Classesโ
Generic interfaces and classes
// Generic interface
interface Box<T> {
value: T;
}
const numBox: Box<number> = { value: 42 };
const strBox: Box<string> = { value: "hello" };
// 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];
}
}
const numStack = new Stack<number>();
numStack.push(1);
numStack.push(2);
Generic Constraintsโ
Generic constraints
// Constraint: T must have length property
interface HasLength {
length: number;
}
function logLength<T extends HasLength>(arg: T): void {
console.log(arg.length);
}
logLength("hello"); // Valid โ string has length
logLength([1, 2, 3]); // Valid โ array has length
// logLength(42); // Error โ number doesn't have length
Utility Typesโ
Common Built-in Utility Typesโ
TypeScript utility types
interface User {
id: number;
name: string;
email: string;
}
// Partial โ makes all properties optional
type PartialUser = Partial<User>;
const user1: PartialUser = { name: "Alice" }; // Valid
// Required โ makes all properties required
type RequiredUser = Required<PartialUser>;
// Readonly โ makes all properties readonly
type ReadonlyUser = Readonly<User>;
const user2: ReadonlyUser = { id: 1, name: "Bob", email: "bob@example.com" };
// user2.name = "Alice"; // Error โ readonly
// Pick โ select specific properties
type UserPreview = Pick<User, "id" | "name">;
const preview: UserPreview = { id: 1, name: "Alice" };
// Omit โ exclude specific properties
type UserWithoutEmail = Omit<User, "email">;
const user3: UserWithoutEmail = { id: 1, name: "Alice" };
// Record โ create object type with specific keys and value type
type Scores = Record<string, number>;
const scores: Scores = { math: 90, english: 85 };
Function Typesโ
Function Signaturesโ
Function type annotations
// Function declaration
function add(a: number, b: number): number {
return a + b;
}
// Arrow function
const multiply = (a: number, b: number): number => a * b;
// Optional parameters
function greet(name: string, greeting?: string): string {
return `${greeting || "Hello"}, ${name}`;
}
// Default parameters
function power(base: number, exponent: number = 2): number {
return base ** exponent;
}
// Rest parameters
function sum(...nums: number[]): number {
return nums.reduce((a, b) => a + b, 0);
}
Function Overloadsโ
Function overloading
// Overload signatures
function process(x: number): number;
function process(x: string): string;
function process(x: number[]): number;
// Implementation signature
function process(x: number | string | number[]): number | string {
if (typeof x === "number") {
return x * 2;
} else if (typeof x === "string") {
return x.toUpperCase();
} else {
return x.reduce((a, b) => a + b, 0);
}
}
process(5); // Returns number
process("hello"); // Returns string
process([1, 2, 3]); // Returns number
Classesโ
Class Syntaxโ
Class definitions in TypeScript
class Point {
x: number;
y: number;
constructor(x: number, y: number) {
this.x = x;
this.y = y;
}
distance(): number {
return Math.sqrt(this.x ** 2 + this.y ** 2);
}
}
const p = new Point(3, 4);
console.log(p.distance()); // 5
Access Modifiersโ
Access modifiers in classes
class BankAccount {
public owner: string; // Accessible everywhere (default)
private balance: number; // Only accessible within class
protected accountNumber: string; // Accessible in class and subclasses
constructor(owner: string, balance: number, accountNumber: string) {
this.owner = owner;
this.balance = balance;
this.accountNumber = accountNumber;
}
deposit(amount: number): void {
this.balance += amount;
}
getBalance(): number {
return this.balance;
}
}
const account = new BankAccount("Alice", 1000, "123");
console.log(account.owner); // Valid
// console.log(account.balance); // Error โ private
console.log(account.getBalance()); // Valid โ public method
Shorthand Constructorโ
Constructor parameter properties
class Point {
// Shorthand โ declares and initializes properties
constructor(public x: number, public y: number) {}
distance(): number {
return Math.sqrt(this.x ** 2 + this.y ** 2);
}
}
const p = new Point(3, 4); // x and y are automatically assigned
Abstract Classesโ
Abstract classes in TypeScript
abstract class Shape {
abstract area(): number; // Must be implemented by subclasses
describe(): string { // Concrete method
return `Area: ${this.area()}`;
}
}
class Circle extends Shape {
constructor(public radius: number) {
super();
}
area(): number {
return Math.PI * this.radius ** 2;
}
}
const circle = new Circle(5);
console.log(circle.describe()); // "Area: 78.54..."
Enumsโ
Numeric Enumsโ
Numeric enum examples
enum Direction {
Up, // 0
Down, // 1
Left, // 2
Right // 3
}
let dir: Direction = Direction.Up;
// Custom starting value
enum Status {
Pending = 1,
Success = 2,
Error = 3
}
String Enumsโ
String enum examples
enum Color {
Red = "RED",
Green = "GREEN",
Blue = "BLUE"
}
let color: Color = Color.Red;
console.log(color); // "RED"
Const Enumsโ
Const enums for performance
const enum Direction {
Up,
Down,
Left,
Right
}
let dir = Direction.Up; // Inlined at compile time, no runtime object
Type Assertionsโ
As Syntaxโ
Type assertions in TypeScript
// Tell TypeScript to treat value as specific type
let value: unknown = "hello";
let length: number = (value as string).length;
// Alternative syntax (not recommended in JSX)
let length2: number = (<string>value).length;
// Non-null assertion
function getElement(id: string): HTMLElement | null {
return document.getElementById(id);
}
const elem = getElement("myId")!; // Assert it's not null
elem.innerHTML = "Hello";
Async/Await with Typesโ
Promise Typesโ
Typed promises
// Function returning Promise
async function fetchData(): Promise<string> {
const response = await fetch("https://api.example.com/data");
const data = await response.text();
return data;
}
// Generic Promise
async function fetchJSON<T>(url: string): Promise<T> {
const response = await fetch(url);
return response.json();
}
interface User {
id: number;
name: string;
}
const user = await fetchJSON<User>("https://api.example.com/user");
console.log(user.name); // TypeScript knows user has name property
Common DSA Patterns with Typesโ
Typed Data Structuresโ
Type-safe data structures
// Stack
class Stack<T> {
private items: T[] = [];
push(item: T): void {
this.items.push(item);
}
pop(): T | undefined {
return this.items.pop();
}
isEmpty(): boolean {
return this.items.length === 0;
}
}
// Queue
class Queue<T> {
private items: T[] = [];
enqueue(item: T): void {
this.items.push(item);
}
dequeue(): T | undefined {
return this.items.shift();
}
}
// Binary Tree Node
class TreeNode<T> {
constructor(
public value: T,
public left: TreeNode<T> | null = null,
public right: TreeNode<T> | null = null
) {}
}
Graph Representationโ
Typed graph structures
// Adjacency list with Map
type Graph<T> = Map<T, T[]>;
function createGraph<T>(): Graph<T> {
return new Map();
}
function addEdge<T>(graph: Graph<T>, from: T, to: T): void {
if (!graph.has(from)) {
graph.set(from, []);
}
graph.get(from)!.push(to);
}
// Weighted graph
interface Edge<T> {
to: T;
weight: number;
}
type WeightedGraph<T> = Map<T, Edge<T>[]>;
Algorithm Return Typesโ
Typed algorithm functions
// Binary search
function binarySearch(arr: number[], target: number): number {
let left = 0, right = arr.length - 1;
while (left <= right) {
const mid = Math.floor((left + right) / 2);
if (arr[mid] === target) return mid;
if (arr[mid] < target) left = mid + 1;
else right = mid - 1;
}
return -1;
}
// Two sum with tuple return
function twoSum(nums: number[], target: number): [number, number] | null {
const map = new Map<number, number>();
for (let i = 0; i < nums.length; i++) {
const complement = target - nums[i];
if (map.has(complement)) {
return [map.get(complement)!, i];
}
map.set(nums[i], i);
}
return null;
}
Type Narrowing Patternsโ
Discriminated Unionsโ
Discriminated union pattern
interface Success {
type: "success";
data: string;
}
interface Error {
type: "error";
message: string;
}
type Result = Success | Error;
function handleResult(result: Result): void {
if (result.type === "success") {
console.log(result.data); // TypeScript knows it's Success
} else {
console.log(result.message); // TypeScript knows it's Error
}
}
Configurationโ
tsconfig.json Essentialsโ
Recommended tsconfig.json for DSA
{
"compilerOptions": {
"target": "ES2020",
"module": "commonjs",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"resolveJsonModule": true,
"outDir": "./dist",
"rootDir": "./src"
},
"include": ["src/**/*"],
"exclude": ["node_modules"]
}
Referencesโ
Telemetry Integration
Completed working through this block? Sync progress to workspace.