TypeScript Cheatsheet
Functions
Use this TypeScript reference while you build software engineering projects, review code for technical interview prep, or polish examples for a software engineer resume.
Function Declarations and Expressions
// Named function declaration function add(a: number, b: number): number { return a + b; } // Function expression const multiply = function(a: number, b: number): number { return a * b; }; // Arrow function const divide = (a: number, b: number): number => a / b; // Arrow function with body const greet = (name: string): string => { return `Hello, ${name}`; }; // Inferred return type (TypeScript infers from the return statement) const square = (n: number) => n * n; // inferred: (n: number) => number
Parameter Types
// Required parameters function greet(name: string, age: number): string { return `${name} is ${age}`; } // Optional parameters (must come after required) function log(message: string, level?: string): void { console.log(`[${level ?? "info"}] ${message}`); } // Default parameters (implicitly optional) function repeat(s: string, times: number = 3): string { return s.repeat(times); } // Rest parameters — collects remaining args as array function sum(first: number, ...rest: number[]): number { return rest.reduce((acc, n) => acc + n, first); } // Destructured parameter with type function display({ title, count = 0 }: { title: string; count?: number }): void { console.log(title, count); } // Named destructure with explicit type alias type Options = { verbose: boolean; timeout: number }; function run({ verbose, timeout }: Options): void {}
Return Types
// Explicit return type function parse(s: string): number { return parseInt(s); } // void — returns undefined function noop(): void {} // never — function never returns (throws or infinite loops) function fail(msg: string): never { throw new Error(msg); } // Async function — always returns Promise<T> async function fetchUser(id: number): Promise<User> { return await fetch(`/users/${id}`).then(r => r.json()); } // Generator — returns Generator<YieldType, ReturnType, NextType> function* range(start: number, end: number): Generator<number> { for (let i = start; i < end; i++) yield i; } // Async generator async function* streamLines(url: string): AsyncGenerator<string> { // yields lines one by one }
Function Overloads
// Declare overload signatures first, then implementation function makeDate(timestamp: number): Date; function makeDate(m: number, d: number, y: number): Date; // Implementation signature (not callable directly) function makeDate(mOrTimestamp: number, d?: number, y?: number): Date { if (d !== undefined && y !== undefined) { return new Date(y, mOrTimestamp, d); } return new Date(mOrTimestamp); } const d1 = makeDate(12345678); const d2 = makeDate(5, 5, 2000); // Overloads with different return types function process(x: string): string; function process(x: number): number; function process(x: string | number): string | number { return typeof x === "string" ? x.toUpperCase() : x * 2; }
Function Types
// Type alias for a function type BinaryOp = (a: number, b: number) => number; const add: BinaryOp = (a, b) => a + b; // Interface with call signature interface Formatter { (input: string, radix?: number): string; } // Callback type type Callback<T> = (err: Error | null, result: T) => void; // Generic function type type Mapper<A, B> = (value: A, index: number) => B; // Variadic function type type Logger = (...args: unknown[]) => void;
Generic Functions
// Single type parameter function identity<T>(value: T): T { return value; } identity<string>("hello"); identity(42); // inferred: number // Multiple type parameters function pair<A, B>(a: A, b: B): [A, B] { return [a, b]; } // Constrained type parameter function getLength<T extends { length: number }>(arg: T): number { return arg.length; } getLength("hello"); // OK getLength([1, 2, 3]); // OK // Keyof constraint function getProperty<T, K extends keyof T>(obj: T, key: K): T[K] { return obj[key]; } // Default type parameter function createArray<T = string>(len: number, fill: T): T[] { return Array(len).fill(fill); }
this Parameter
// Explicit this parameter (fake param, removed at compile time) interface Deck { suits: string[]; cards: number[]; createCardPicker(this: Deck): () => { suit: string; card: number }; } // this: void — function must not use 'this' function noThis(this: void, x: number): number { return x; } // noImplicitThis — requires explicit this type in methods const obj = { value: 42, getValue(this: typeof obj): number { return this.value; } };
Higher-Order Functions
// Function that returns a function function multiplier(factor: number): (n: number) => number { return (n) => n * factor; } const triple = multiplier(3); triple(5); // 15 // Function that accepts a function function applyTwice<T>(fn: (x: T) => T, value: T): T { return fn(fn(value)); } applyTwice((x: number) => x + 1, 5); // 7 // Compose function compose<A, B, C>(f: (b: B) => C, g: (a: A) => B): (a: A) => C { return (a) => f(g(a)); } // Curry (manual) function curry<A, B, C>(fn: (a: A, b: B) => C): (a: A) => (b: B) => C { return (a) => (b) => fn(a, b); }
Optional and Default Parameters in Depth
// Optional parameters become T | undefined inside the function function find(arr: string[], pred?: (s: string) => boolean): string | undefined { if (!pred) return arr[0]; return arr.find(pred); } // Default parameters allow passing undefined explicitly function greet(name: string = "World"): string { return `Hello, ${name}!`; } greet(); // "Hello, World!" greet(undefined); // "Hello, World!" greet("Alice"); // "Hello, Alice!" // Default can be an expression evaluated at call time function now(date: Date = new Date()): Date { return date; }
Async Functions and Promises
// Basic async/await async function fetchData(url: string): Promise<string> { const res = await fetch(url); return res.text(); } // Error handling async function safeLoad(url: string): Promise<string | null> { try { const res = await fetch(url); if (!res.ok) return null; return await res.text(); } catch { return null; } } // Promise.all — parallel, all must succeed async function loadAll(urls: string[]): Promise<string[]> { return Promise.all(urls.map(url => fetchData(url))); } // Promise.allSettled — parallel, handles failures async function loadSafe(urls: string[]) { const results = await Promise.allSettled(urls.map(fetchData)); return results.map(r => r.status === "fulfilled" ? r.value : null); } // Promise.race — first to resolve/reject wins async function withTimeout<T>(promise: Promise<T>, ms: number): Promise<T> { const timeout = new Promise<T>((_, reject) => setTimeout(() => reject(new Error("Timeout")), ms) ); return Promise.race([promise, timeout]); }
Type Predicates and Assertion Functions
// Type predicate — return type is "val is T" function isString(val: unknown): val is string { return typeof val === "string"; } function isError(val: unknown): val is Error { return val instanceof Error; } // Usage const values: unknown[] = [1, "two", true]; const strings = values.filter(isString); // string[] // Assertion function — asserts a condition function assert(condition: boolean, msg: string): asserts condition { if (!condition) throw new Error(msg); } function assertDefined<T>(val: T | undefined): asserts val is T { if (val === undefined) throw new Error("Expected defined value"); } // After calling assertDefined, TypeScript knows val is T function process(val: string | undefined) { assertDefined(val); val.toUpperCase(); // OK — val is string here }
Function Signatures in Interfaces and Types
// Inline function type let fn: (a: string) => number; // Named function type type Predicate<T> = (val: T) => boolean; type Transform<A, B> = (val: A) => B; type Effect<T> = (val: T) => void; type AsyncOp<T, R> = (val: T) => Promise<R>; // Method vs property function (subtly different for `this`) interface Api { get(url: string): Promise<unknown>; // method: covariant (bivariant in practice) post: (url: string) => Promise<unknown>; // property: stricter } // Overloaded interface method interface Printer { print(doc: string): void; print(doc: string, copies: number): void; }
Contextual Typing and Callbacks
// TypeScript infers callback parameter types from context const nums = [1, 2, 3]; nums.forEach(n => n.toFixed()); // n inferred as number // addEventListener infers event type document.addEventListener("click", (e) => { e.clientX; // MouseEvent — inferred }); // Map callback — inferred const doubled = nums.map(n => n * 2); // n: number // Generic callback with explicit typing function transform<T, U>(arr: T[], fn: (item: T, i: number) => U): U[] { return arr.map(fn); } transform([1, 2, 3], (n, i) => `${i}:${n}`); // string[]
Parameter Spread and Tuple Rest
// Spread tuple as arguments function point(x: number, y: number, z: number): void {} const coords: [number, number, number] = [1, 2, 3]; point(...coords); // OK // Generic rest parameters with tuple function bind<T extends unknown[], R>( fn: (...args: T) => R, ...args: T ): () => R { return () => fn(...args); } // Variadic tuple types type Concat<T extends unknown[], U extends unknown[]> = [...T, ...U]; type AB = Concat<[string, number], [boolean]>; // [string, number, boolean]