Skip to main content
Практика завдань

Злиття декларацій у TypeScript

Що таке об'єднання декларацій?

Об'єднання декларацій — це здатність TypeScript об'єднувати кілька декларацій з однаковим ім'ям в одне визначення. Це унікальна функція, яка не існує в більшості інших мов.


Об'єднання інтерфейсів

Найбільш поширена форма — кілька декларацій інтерфейсів з однаковим ім'ям об'єднуються:

typescript
interface User { name: string; } interface User { age: number; } interface User { email: string; } // Усі три об'єднуються в: // interface User { // name: string; // age: number; // email: string; // } const user: User = { name: "Alice", age: 25, email: "alice@example.com" }; // Має мати ВСІ властивості

type не може бути об'єднаний

typescript
type User = { name: string }; type User = { age: number }; // ❌ Помилка: Дублюючий ідентифікатор 'User'

Це ключова різниця між interface і type.

Розширення модулів

Розширюйте існуючі модулі, додаючи декларації:

typescript
// Розширення Express Request declare module "express" { interface Request { user?: { id: string; role: string; }; } } // Тепер req.user доступний у всіх обробниках app.get("/profile", (req, res) => { console.log(req.user?.id); // ✅ TypeScript це розпізнає });

Розширення сторонніх бібліотек

typescript
// Додати власні матчери до Jest declare module "@jest/expect" { interface Matchers<R> { toBeWithinRange(floor: number, ceiling: number): R; } } // Розширення Window declare global { interface Window { analytics: { track(event: string, data?: object): void; }; } } window.analytics.track("page_view"); // ✅

Об'єднання простору імен

typescript
namespace Validation { export function isEmail(value: string): boolean { return /^[^@]+@[^@]+$/.test(value); } } namespace Validation { export function isPhone(value: string): boolean { return /^\+?\d{10,}$/.test(value); } } // Обидві функції доступні: Validation.isEmail("test@test.com"); // ✅ Validation.isPhone("+380123456789"); // ✅

Об'єднання перерахувань

typescript
enum Color { Red = 0, Green = 1, } enum Color { Blue = 2, Yellow = 3, } // Об'єднані: Color.Red, Color.Green, Color.Blue, Color.Yellow

Практичні випадки використання

Додавання типів до бібліотек без типів

typescript
// custom.d.ts declare module "untyped-library" { export function doSomething(input: string): number; export const VERSION: string; }

Змінні середовища

typescript
// env.d.ts declare namespace NodeJS { interface ProcessEnv { NODE_ENV: "development" | "production" | "test"; DATABASE_URL: string; JWT_SECRET: string; PORT?: string; } } process.env.DATABASE_URL; // ✅ Типізовано як рядок

Правила об'єднання

ДеклараціяМоже об'єднуватися з
ІнтерфейсІнтерфейс ✅
Простір іменПростір імен ✅, Клас ✅, Функція ✅, Перерахування ✅
КласПростір імен ✅
ФункціяПростір імен ✅
ПерерахуванняПерерахування ✅, Простір імен ✅
Псевдонім типуНічого ❌

Важливо:

Об'єднання декларацій найбільш корисне для розширення модулів — розширення типів сторонніх бібліотек. Об'єднання інтерфейсів також є причиною, чому interface віддається перевага над type для публічних API — споживачі можуть їх розширювати. Використовуйте declare module для розширення бібліотек і declare global для розширення глобальної області.

Коротка відповідь

Для співбесіди
Premium

Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.

Дочитали статтю?
Практика завдань