TypeScript Function Overloads
debt(d3/e3/b3/t5)
Closest to 'default linter catches the common case' (d3). Common mistakes like putting the implementation signature before overload signatures or making the implementation narrower than the overloads are caught by the TypeScript compiler itself at compile time — essentially the default toolchain. No specialist tools are listed in detection_hints.tools (empty), but the TypeScript compiler as a standard part of the ecosystem catches ordering and compatibility errors immediately.
Closest to 'simple parameterised fix' (e3). The quick_fix describes replacing a union return type with overload signatures, or correcting overload ordering/narrowing issues. This is a localised refactor within one function's declaration — more than a single-line swap but contained to the function signature and implementation block, not spread across multiple files.
Closest to 'localised tax' (b3). Overloads apply to individual functions and their callers. The misconception and common_mistakes indicate the cognitive tax is felt at the function definition site and by direct callers, but the rest of the codebase is generally unaffected. The applies_to field is unspecified, suggesting no system-wide reach.
Closest to 'notable trap' (t5). The canonical misconception — that the implementation signature is visible to callers — is a documented gotcha that many developers encounter when first using TypeScript overloads. The 'obvious' assumption that what you write in the implementation is what callers see contradicts TypeScript's actual behaviour, but it's a learnable and well-documented surprise rather than a catastrophic or architecturally dangerous one.
Also Known As
TL;DR
Explanation
A function overload consists of two or more overload signatures (no body) followed by one implementation signature (with body). TypeScript uses the overload signatures for type checking and IDE autocomplete — the implementation signature is hidden from callers. Overloads are useful when the return type depends on the input type (e.g. createElement('div') returns HTMLDivElement, createElement('canvas') returns HTMLCanvasElement), or when a function accepts fundamentally different argument shapes. The implementation must be compatible with all overload signatures. Method overloads work the same way in classes.
Common Misconception
Why It Matters
Common Mistakes
- Putting the implementation signature before the overload signatures — TypeScript requires all overload signatures first, then the implementation.
- Making the implementation signature narrower than the overloads — the implementation must accept the union of all overload parameters.
- Using overloads when conditional types or generics would be cleaner — overloads are best for a small number of distinct cases; for many cases use generics with conditional return types.
- Exposing too many overloads — each overload adds cognitive load; prefer 2–4 well-chosen overloads over exhaustive enumeration.
Code Examples
// ❌ Union return type — caller must narrow every time
function parseInput(input: string | number): string | number {
if (typeof input === 'string') return input.toUpperCase();
return input * 2;
}
const result = parseInput('hello');
// result: string | number — TypeScript doesn't know it's string
result.toUpperCase(); // Error: Property 'toUpperCase' does not exist on type 'string | number'
// ✅ Overloads — return type matches input type
function parseInput(input: string): string;
function parseInput(input: number): number;
function parseInput(input: string | number): string | number {
if (typeof input === 'string') return input.toUpperCase();
return input * 2;
}
const s = parseInput('hello'); // TypeScript knows: string
s.toUpperCase(); // ✓ No error
const n = parseInput(42); // TypeScript knows: number
n.toFixed(2); // ✓ No error
// Class method overload
class EventEmitter {
on(event: 'data', listener: (data: Buffer) => void): this;
on(event: 'error', listener: (err: Error) => void): this;
on(event: string, listener: Function): this {
// implementation
return this;
}
}