Declaration Merging & Module Augmentation
Уникальная фича TS, без которой не расширить lib.d.ts, jest, express и т.п. На интервью просят: «Как добавить req.user в Express?» — через module augmentation. Красный флаг — путать declare module с declare namespace, не знать про global augmentation.
Слияние interface и namespace:
interface Config { host: string }interface Config { port: number } // сливаетсяconst c: Config = { host: 'h', port: 80 };
// namespace + interface (companion)class Service {}namespace Service { export const VERSION = '1.0'; export interface Options { retries: number }}const v = Service.VERSION;const o: Service.Options = { retries: 3 };Module augmentation — расширяем чужой модуль:
import 'express';
declare module 'express-serve-static-core' { interface Request { user?: { id: string; role: 'admin' | 'user' }; }}
// теперь в коде:import type { Request } from 'express';function h(req: Request) { return req.user?.id; }Global augmentation — лезем в глобальные типы:
export {}; // делает файл модулем
declare global { interface Window { analytics: { track(event: string): void }; } // расширяем встроенный тип interface Array<T> { last(): T | undefined; }}
window.analytics.track('login');[1, 2, 3].last(); // 3Итог: Declaration merging работает у interface/namespace; для расширения внешних модулей — declare module ‘name’, для глобалей — declare global.