Module Augmentation
Module Augmentation — механизм TypeScript, позволяющий дополнять существующие объявления типов модулей или глобального пространства имён из внешнего файла без изменения исходного кода библиотеки.
Зачем нужно
Сторонние библиотеки иногда позволяют добавлять свойства в свои объекты через middleware или плагины. Module augmentation позволяет отразить это расширение в системе типов без форка @types пакета, что сохраняет типобезопасность в проектах с кастомными расширениями.
Где используется
- Добавление
req.userк ExpressRequestчерез middleware - Расширение типов
process.envдля конкретного проекта - Добавление свойств к
WindowилиglobalThis - Дополнение типов библиотек (Vue, axios, Fastify)
- Declaration merging для интерфейсов из npm-пакетов
Основной контент
Базовый синтаксис
Файл должен быть модулем (содержать import или export). Используется блок declare module "имя-модуля".
// src/types/express.d.ts
import { User } from "../models/user";
declare module "express-serve-static-core" {
interface Request {
user?: User;
correlationId: string;
}
}
// Теперь в маршрутах:
app.get("/profile", (req, res) => {
if (req.user) {
res.json(req.user.name); // TypeScript знает тип user
}
});
Расширение process.env
// src/types/env.d.ts
declare namespace NodeJS {
interface ProcessEnv {
NODE_ENV: "development" | "production" | "test";
DATABASE_URL: string;
PORT?: string;
JWT_SECRET: string;
}
}
// В коде:
const dbUrl = process.env.DATABASE_URL; // string (не undefined)
const port = process.env.PORT ?? "3000"; // string | undefined → string
Расширение Window
// src/types/global.d.ts
export {}; // делаем файл модулем
declare global {
interface Window {
analytics: {
track(event: string, data?: Record<string, unknown>): void;
};
__APP_VERSION__: string;
}
}
// В браузерном коде:
window.analytics.track("page_view", { path: location.pathname });
console.log(window.__APP_VERSION__);
Declaration merging — добавление к существующему интерфейсу
// Из библиотеки: interface Theme { colors: { primary: string } }
// В нашем коде:
import "some-ui-library";
declare module "some-ui-library" {
interface Theme {
spacing: { sm: number; md: number; lg: number };
}
}
// Теперь Theme содержит оба набора свойств
const theme: Theme = {
colors: { primary: "#fff" },
spacing: { sm: 4, md: 8, lg: 16 },
};
Настройка tsconfig.json для augmentation
{
"compilerOptions": {
"typeRoots": ["./src/types", "./node_modules/@types"]
},
"include": ["src/**/*"]
}
Частые ошибки
- Файл не является модулем — без
import/exportaugmentation не работает; добавьтеexport {}если нет других экспортов. - Использовать
interfaceвместоnamespace NodeJS— дляprocess.envнужноdeclare namespace NodeJS { interface ProcessEnv }. - Augmentation не подхватывается — убедитесь что файл включён в
tsconfig.jsonчерезincludeилиtypeRoots. - Augmenting type aliases — работает только с
interfaceиnamespace;typeнельзя дополнить через declaration merging.
Связанные темы
- interface -- объявление и использование
- Расширение интерфейсов -- extends
- tsconfig.json -- основные опции
- _MOC TypeScript