Однакове ім'я інтерфейсів
1. Якщо два інтерфейси мають однакове ім'я...
...TypeScript не видасть помилку, а об'єднає їх (складе всі поля разом).
Ця поведінка називається declaration merging - "злиття оголошень".
Приклад
interface User {
id: number;
}
interface User {
name: string;
}
const u: User = {
id: 1,
name: "Tim",
};Результат: TypeScript об'єднав обидва інтерфейси в один:
// Компілятор бачить це так:
interface User {
id: number;
name: string;
}2. Як працює об'єднання
Коли TypeScript бачить кілька інтерфейсів з однаковим ім'ям:
- Він не замінює старе оголошення новим.
- Він об'єднує їх - додаючи поля, методи і типи з обох.
- Якщо та сама властивість зустрічається в обох - TypeScript перевіряє, чи сумісні типи цих властивостей.
Приклад з однаковими типами полів
interface Product {
id: number;
}
interface Product {
title: string;
}
const p: Product = { id: 10, title: "Shirt" }; // OKОб'єднання успішне - поля різні.
Приклад з конфліктуючими типами
interface Product {
id: number;
}
interface Product {
id: string;
}
// Помилка: типи несумісні
const p: Product = { id: "10" };TypeScript не може об'єднати
numberіstringдля однієї і тієї ж властивості.
3. Можна об'єднувати не тільки поля, а й методи
interface Logger {
log(msg: string): void;
}
interface Logger {
warn(msg: string): void;
}
const logger: Logger = {
log: (msg) => console.log(msg),
warn: (msg) => console.warn(msg),
};TypeScript створить об'єднаний інтерфейс з обома методами.
4. Порядок об'єднання має значення (в особливих випадках)
Якщо методи мають однакові імена, але різні сигнатури - TypeScript об'єднує їх як перевантаження, і порядок оголошення впливає на пріоритет.
interface Example {
doThing(a: number): void;
}
interface Example {
doThing(a: string): void;
}
const e: Example = {
doThing(a) {
console.log(a);
},
};Тут інтерфейс
Exampleмає дві сигнатури методу -doThing(a: string)іdoThing(a: number).
5. Де це використовується на практиці
Розширення типів із бібліотек
Наприклад, можна додати власні поля в інтерфейс Express.Request:
// у твоєму проєкті
declare module "express" {
interface Request {
user?: { id: number; name: string };
}
}TypeScript об'єднає твоє оголошення з оригінальним інтерфейсом Express. Тепер
req.userбуде типізований!
Розширення глобальних типів
interface Window {
myAppVersion?: string;
}
window.myAppVersion = "1.2.3";Тепер властивість
window.myAppVersionкоректно типізована, хоча її не було в стандартному інтерфейсі.
6. На відміну від type
type не підтримує об'єднання:
type User = { id: number };
type User = { name: string }; // Помилка: повторне визначення типуУ
type- строгі межі: одне ім'я = одне оголошення.А інтерфейси, навпаки, можуть об'єднуватися - саме тому їх часто використовують для розширення наявних API.
Підсумок
Якщо в TypeScript оголосити два інтерфейси з однаковим ім'ям, вони об'єднаються в один.
Це називається declaration merging.
Правила:
- усі поля об'єднуються в один інтерфейс;
- якщо та сама властивість повторюється - типи повинні бути сумісними;
- методи з однаковими іменами об'єднуються як перевантаження;
- працює лише з
interface, не зtype.Це використовується для:
- розширення бібліотек (Express, React, Node API);
- додавання кастомних властивостей глобальним типам (
Window,Documentтощо).
Коротка відповідь
Для співбесідиКоротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.