Вопрос проверяет умение моделировать разные варианты сущностей и корректно описывать их в системе типов.
Для объектов с разным набором полей обычно используют union-типы. Каждый вариант описывается своим типом или интерфейсом. TypeScript умеет сужать типы по проверкам. Это позволяет безопасно работать с разными структурами данных. Такой подход делает код понятным и защищённым от ошибок.
На практике часто встречаются сущности, которые имеют общие поля, но различаются деталями.
Самый распространённый способ — union-типы:
type User = Admin | Guest;
interface Admin {
role: "admin";
permissions: string[];
}
interface Guest {
role: "guest";
expiresAt: Date;
}
Здесь:
User может быть разного вида
набор полей зависит от роли
TypeScript умеет автоматически определять конкретный вариант:
function processUser(user: User) {
if (user.role === "admin") {
user.permissions; // доступно
}
}
Это называется type narrowing.
Часто выносят общие свойства:
interface BaseUser {
id: number;
}
interface Admin extends BaseUser {
role: "admin";
}
interface Guest extends BaseUser {
role: "guest";
}
В зависимости от задачи можно использовать:
optional-поля (хуже для строгой типизации)
дженерики
mapped-типы
Union-типы позволяют точно описывать объекты с разным набором полей. Это основной инструмент моделирования сложных доменных сущностей в TypeScript.