Functions, Overloads & Typing Patterns
📖 Concept
TypeScript provides rich typing for functions — from basic parameter/return types to generics, overloads, and advanced patterns like this typing.
Function type expressions: (param: Type) => ReturnType
Optional and default parameters: param?: Type or param: Type = defaultValue
Rest parameters: ...args: Type[]
Function overloads: Multiple signatures for different input/output combinations
Function Overloads let you define multiple call signatures for a single function. The compiler chooses the right signature based on the arguments. The implementation signature must be compatible with ALL overload signatures.
this typing: TypeScript can type the this parameter explicitly — useful for callbacks that need a specific context.
Callback typing patterns:
(data: T) => void— Standard callback(err: Error | null, data?: T) => void— Node.js error-first callback() => Promise<T>— Async factory
🏠 Real-world analogy: Function overloads are like a Swiss Army knife — the same tool (function name) provides different tools (behavior) depending on how you open it (what arguments you pass).
💻 Code Example
1// Basic function typing2function add(a: number, b: number): number {3 return a + b;4}56// Arrow function type7const multiply: (a: number, b: number) => number = (a, b) => a * b;89// Optional and default parameters10function greet(name: string, greeting: string = "Hello"): string {11 return `${greeting}, ${name}!`;12}13greet("Alice"); // "Hello, Alice!"14greet("Alice", "Hola"); // "Hola, Alice!"1516// Rest parameters17function sum(...numbers: number[]): number {18 return numbers.reduce((acc, n) => acc + n, 0);19}2021// ⭐ Function Overloads22function createElement(tag: "a"): HTMLAnchorElement;23function createElement(tag: "canvas"): HTMLCanvasElement;24function createElement(tag: "input"): HTMLInputElement;25function createElement(tag: string): HTMLElement;26function createElement(tag: string): HTMLElement {27 return document.createElement(tag);28}29const anchor = createElement("a"); // Type: HTMLAnchorElement30const canvas = createElement("canvas"); // Type: HTMLCanvasElement3132// Practical overload: different return based on input33function parseInput(input: string): string;34function parseInput(input: number): number;35function parseInput(input: string | number): string | number {36 if (typeof input === "string") return input.trim();37 return Math.round(input);38}3940// Typing 'this'41interface Button {42 label: string;43 onClick(this: Button): void;44}45const button: Button = {46 label: "Submit",47 onClick() {48 console.log(this.label); // 'this' is typed as Button49 }50};5152// Generic function (preview — deep dive in Phase 2)53function identity<T>(value: T): T {54 return value;55}56const str = identity("hello"); // Type: string57const num = identity(42); // Type: number5859// Function type with generics60type Mapper<T, U> = (item: T, index: number) => U;61const toLength: Mapper<string, number> = (s) => s.length;6263// Void vs undefined return64type VoidFn = () => void;65const fn: VoidFn = () => { return true; }; // ✅ No error! void ignores return66// This is intentional — allows array.forEach() to accept callbacks that return values
🏋️ Practice Exercise
Mini Exercise:
- Write overloaded function signatures for a
formatfunction that accepts string → string or number → string - Create a typed callback pattern:
function fetchData(url: string, cb: (err: Error | null, data?: string) => void) - Type a method with explicit
thisparameter for a class-like object - Write a generic identity function and observe how TypeScript infers
T - Explain why
() => voidallows returning values but() => undefineddoes not
⚠️ Common Mistakes
Confusing the overload signatures with the implementation — the implementation signature is NOT callable directly; only the overload signatures are visible to callers
Thinking
() => voidmeans 'returns undefined' —voidmeans the return value is IGNORED, not that it must beundefined. Callbacks typed asvoidcan return anythingForgetting that optional parameters must come after required ones —
(a?: string, b: number)is invalidNot typing
thisin callbacks that depend on context — leads to runtime errors whenthisis the wrong objectOver-using overloads when a union parameter or generic would be simpler — overloads should be a last resort for complex input/output mappings
💼 Interview Questions
🎤 Mock Interview
Practice a live interview for Functions, Overloads & Typing Patterns