Загрузка…
Загрузка…
TypeScript · middle · сложность 6
Overloads — несколько публичных call signatures и одна implementation signature (её вызывающие не видят). Нужны, когда разным формам входа соответствуют разные типы выхода. Часто честнее и проще union или generic — к overloads тянитесь последними.
Перегруженная функция — много контрактов, одно тело. Сверху пишут узкие публичные сигнатуры, снизу — широкую реализацию, покрывающую все случаи. Callers видят только публичные; implementation должна быть совместима со всеми.
Минусы: шумно, легко ошибиться в порядке сигнатур (TS пробует сверху вниз), implementation часто уходит в any/unknown внутри. Альтернативы: union аргументов + narrowing, generics, function type с conditional return.
// Overloads: input shape determines output type
function parse(x: string): string[]; // overload 1 (public)
function parse(x: number): number; // overload 2 (public)
function parse(x: string | number): string[] | number { // impl (hidden)
return typeof x === 'string' ? x.split('') : x * 2;
}
const a = parse('hi'); // string[]
const b = parse(3); // number
// parse(x as string | number); // ❌ no PUBLIC overload accepts a union
// ❌ Order matters — a broad overload first shadows the specific one
function get(k: string): unknown;
function get(k: 'id'): number; // unreachable — never picked
// ✅ specific first
function get2(k: 'id'): number;
function get2(k: string): unknown;// ✅ Often better: a generic + lookup type instead of overloads
interface Events { click: MouseEvent; key: KeyboardEvent; }
function on<K extends keyof Events>(type: K, cb: (e: Events[K]) => void) {/*...*/}
on('click', e => e.button); // e is MouseEvent — one signature, precise output
// ✅ Or a union return when inputs don't change the output shape
function toArray<T>(x: T | T[]): T[] {
return Array.isArray(x) ? x : [x];
}Overloads — когда нельзя честно выразить связь вход→выход union/generic; иначе предпочитайте более простые средства типов.