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"]
}