TS TypeScript  ·  30 вопросов  ·  ~85 мин  ·  ⏱ Таймер 25:00  ·  Сложный  · 

Архитектура TypeScript-кодовой базы

Профессиональный тест по теме «Архитектура TypeScript-кодовой базы»: сложные фрагменты кода, архитектурные компромиссы, диагностика и надёжность. Вопросы требуют читать код, сопоставлять статические гарантии с поведением JavaScript и выбирать решение, которое не рассыплется при развитии проекта.

Отвечено: 0 из 30
⏱ --:--
0%
💡 Инструкция: Выберите один ответ из пяти. На 30 вопросов отведено 85 минут. Код читайте построчно: часть заданий проверяет не результат JavaScript, а то, что TypeScript способен доказать до запуска.
Вопрос 1 из 30
Почему экспорт конкретного класса слабее экспорта роли?
TypeScript
export class SqlUserRepository {
  constructor(
    public readonly pool: Pool,
    public readonly mapper: OrmMapper
  ) {}
  find(id: UserId): Promise<User | undefined> { /* ... */ }
}
Вопрос 2 из 30
Как satisfies помогает объекту публичного API?
TypeScript
const api = {
  load(id: string) { return Promise.resolve(id); },
  version: "v1"
} satisfies PublicApi;
Вопрос 3 из 30
Как избежать случайного экспорта внутреннего helper из barrel?
TypeScript
// index.ts
export * from "./service";
Вопрос 4 из 30
Что считать публичным контрактом внутри монолита?
Вопрос 5 из 30
Когда возвращать readonly-представление?
Вопрос 6 из 30
Какое направление зависимости предпочтительно?
TypeScript
// order-domain needs to store an order
// sql-adapter knows database details
Вопрос 7 из 30
Почему тип из ORM не стоит использовать как доменную сущность?
TypeScript
type User = Prisma.User;
Вопрос 8 из 30
Где собирать реализации зависимостей?
TypeScript
const repository = new SqlUserRepository(pool);
const service = new UserService(repository);
Вопрос 9 из 30
Почему папочная структура сама не гарантирует слои?
Вопрос 10 из 30
Когда отдельный слой является лишним?
Вопрос 11 из 30
Почему catch и повторный throw одного Error могут потерять смысл слоя?
TypeScript
try {
  await db.insert(order);
} catch (error) {
  throw error;
}
Вопрос 12 из 30
Как размеченное объединение результата отличается от исключения?
TypeScript
type ReserveResult =
  | { ok: true; reservation: Reservation }
  | { ok: false; reason: "sold_out" | "invalid_period" };
Вопрос 13 из 30
Почему error instanceof SomePackageError связывает слой?
TypeScript
if (error instanceof VendorTimeoutError) { /* ... */ }
Вопрос 14 из 30
Какие ошибки включать в публичный union?
Вопрос 15 из 30
Как сохранить исходную причину без утечки клиенту?
Вопрос 16 из 30
Почему добавление обязательного параметра ломает потребителей?
TypeScript
// было
createUser(name: string)
// стало
createUser(name: string, locale: string)
Вопрос 17 из 30
Как options-объект облегчает развитие API?
TypeScript
createUser({ name, locale: "ru", notify: true });
Вопрос 18 из 30
Как объявить устаревший API без немедленного удаления?
TypeScript
/** @deprecated Use createUser(options) */
export function createLegacyUser(name: string): User;
Вопрос 19 из 30
Что проверять перед выпуском изменения публичного типа?
Вопрос 20 из 30
Когда новый вариант union является breaking change?
Вопрос 21 из 30
Что должен подтвердить типовой тест адаптера SqlUserRepository?
TypeScript
interface UserReader { find(id: UserId): Promise<UserSummary | undefined>; }
declare class SqlUserRepository {
  find(id: UserId): Promise<UserSummary | undefined>;
  runRawSql(sql: string): Promise<unknown>;
}
declare const repo: SqlUserRepository;
const reader: UserReader = repo;
Вопрос 22 из 30
Какой отрицательный пример защищает границу между сервисом и адаптером?
TypeScript
declare const reader: UserReader;
// @ts-expect-error — сырой SQL не входит в порт
reader.runRawSql("select 1");
Вопрос 23 из 30
Почему одной проверки implements недостаточно для сервиса оплаты?
TypeScript
interface PaymentGateway { charge(req: ChargeRequest): Promise<ChargeResult>; }
class StripeGateway implements PaymentGateway {
  async charge(req: ChargeRequest): Promise<ChargeResult> { /* ... */ throw new Error(); }
}
Вопрос 24 из 30
После рефакторинга use case стал возвращать Promise<unknown> вместо Promise<UserSummary>. Что поймает регрессию раньше?
Вопрос 25 из 30
Какой набор тестов лучше защищает границу слоя приложения?
Вопрос 26 из 30
Какой вариант публичного API проще развивать без каскада перегрузок?
TypeScript
export interface CreateUserOptions {
  name: string;
  locale?: string;
  notify?: boolean;
}
export function createUser(options: CreateUserOptions): Promise<UserSummary>;
Вопрос 27 из 30
Какая деталь в публичном результате сильнее всего нарушает границу слоёв?
TypeScript
export type FindUserResult =
  | { ok: true; user: UserSummary; entity: OrmUserEntity }
  | { ok: false; reason: "not_found" };
Вопрос 28 из 30
В результат операции добавляется вариант rate_limited. Какой контракт делает изменение заметным там, где его нужно обработать?
TypeScript
type ChargeResult =
 | { kind: "approved"; id: TransactionId }
 | { kind: "declined"; reason: string }
 | { kind: "rate_limited"; retryAfterMs: number };
Вопрос 29 из 30
Как проверить совместимость изменения публичного порта до выпуска?
Вопрос 30 из 30
Какой симптом указывает на переусложнённую архитектуру типов?

Ответьте на все 30 вопросов, чтобы получить результат

🔗 Встроить тест на свой сайт (iframe) ▼

Скопируйте код и вставьте в любое место на вашем сайте:

Также доступна прямая ссылка на embed-страницу