🎁 Зарегистрируйтесь и получите до 30 минут бесплатного использования онлайн-ИИ. Банковская карта не требуется.

Вопросы и ответы для собеседования по TypeScript (2026): типы, дженерики и сужение типов

October 9, 2026
20 вопросов для собеседования по TypeScript с ответами, проверенные в строгом режиме: type против interface, any против unknown, объединения, дженерики, утилитарные типы и структурная типизация.
Вопросы и ответы для собеседования по TypeScript (2026): типы, дженерики и сужение типов
вопросы для собеседования по typescript
собеседование по typescript
type против interface
any против unknown typescript
дженерики typescript собеседование

Собеседования по TypeScript проверяют, понимаете ли вы систему типов, а не только синтаксис. Ниже — 20 вопросов с ответами: от основ до тех, что отличают тех, кто просто использует TypeScript, от тех, кто понимает, почему он работает именно так. Код компилировался компилятором TypeScript в strict-режиме перед публикацией, а приведённые сообщения об ошибках — настоящие.

Основы

1. Что TypeScript добавляет к JavaScript?

Статическую систему типов, которая проверяется во время компиляции, а затем стирается. На выходе получается обычный JavaScript, поэтому типы не имеют ни стоимости во время выполнения, ни присутствия в рантайме. Последний пункт важен: вы не можете проверить тип через typeof во время выполнения, если только не напишете проверку сами.

2. В чём разница между type и interface?

Оба описывают форму объекта и часто взаимозаменяемы. Практические различия:

interfacetype
Слияние объявленийДа, два объявления объединяютсяНет, дублирующееся имя — это ошибка
Объединения и примитивыНе может их выразитьМожет их выразить, например объединение number и string
РасширениеextendsПересечение через &
Mapped- и условные типыНетДа

Если объявить interface A дважды, поля объединятся. Если объявить type B дважды, получите error TS2300: Duplicate identifier 'B'. Частое правило: используйте interface для публичных форм объектов, которые могут расширять другие, а type — для всего остального.

3. В чём разница между any, unknown и never?

  • any отключает проверку. Дозволено всё, а ошибки прячутся.
  • unknown — безопасная версия. В него можно присвоить что угодно, но перед использованием нужно сузить тип. Вызов x.toFixed() для unknown падает с error TS18046: 'x' is of type 'unknown'.
  • never — тип значений, которых не может существовать, например функции, которая всегда бросает исключение. Полезен для проверок на исчерпываемость.

Предпочитайте unknown вместо any для значений, тип которых вы не контролируете, например для распарсенного JSON.

4. Что делает strict-режим?

Он включает группу проверок, важнейшие из которых — strictNullChecks (так что null и undefined становятся отдельными типами) и noImplicitAny. С ним использование опционального значения без проверки даёт error TS18048: 'x' is possibly 'undefined'. Новые проекты стоит начинать со включённым strict.

5. В чём разница между readonly и const?

const запрещает переприсваивание переменной. readonly запрещает присваивание свойству. Запись в readonly-свойство даёт error TS2540: Cannot assign to 'n' because it is a read-only property. Ни то, ни другое не делает сам объект глубоко неизменяемым.

Типы на практике

6. Что такое объединённые типы и как их сужать?

Объединение означает «один из этих типов». Сужение использует проверки, которые понимает компилятор:

type Id = number | string;
function describe(id: Id): string {
  if (typeof id === "string") return id.toUpperCase();
  return id.toFixed(1);
}

Внутри if переменная id имеет тип string. После него компилятор знает, что это number. Другие инструменты сужения — instanceof, оператор in, проверки на равенство и пользовательские type guard-функции.

7. Что такое размеченное объединение?

Это объединение, в котором у каждого члена есть общее литеральное поле — дискриминант, — различающее их:

type Shape =
  | { kind: "circle"; r: number }
  | { kind: "sq"; s: number };

function assertNever(x: never): never {
  throw new Error("unexpected " + x);
}

function area(s: Shape): number {
  switch (s.kind) {
    case "circle": return Math.PI * s.r ** 2;
    case "sq": return s.s ** 2;
    default: return assertNever(s);
  }
}

Если позже вы добавите новую форму и забудете case, ветка default перестанет компилироваться, потому что s больше не never. Это и есть проверка на исчерпываемость.

8. Что такое дженерики и зачем их использовать?

Они позволяют функции или типу работать с множеством типов, сохраняя связь между ними:

function first<T>(xs: T[]): T | undefined { return xs[0]; }
function pick<T, K extends keyof T>(o: T, k: K): T[K] { return o[k]; }

first([1, 2]) возвращает number | undefined, а не any. pick(user, "name") возвращает тип name. Ограничение extends keyof T не даёт передать несуществующий ключ.

9. Какие есть распространённые utility-типы?

UtilityЧто делает
Partial<T>Делает каждое свойство опциональным
Required<T>Делает каждое свойство обязательным
Readonly<T>Делает каждое свойство readonly
Pick<T, K>Оставляет только перечисленные ключи
Omit<T, K>Удаляет перечисленные ключи
Record<K, V>Тип объекта с ключами K и значениями V
ReturnType<F>Возвращаемый тип функционального типа

10. Что такое mapped-типы?

Они создают новый тип, проходя по ключам другого. Сам Partial записывается как { [K in keyof T]?: T[K] }. Понимание этого показывает, что вы разбираетесь в utility-типах, а не заучили их.

11. Что такое as const?

Это указание компилятору вывести самый узкий тип и пометить всё как readonly. const arr = [1, 2, 3] as const имеет тип readonly [1, 2, 3], и arr.push(4) падает с error TS2339: Property 'push' does not exist on type 'readonly [1, 2, 3]'. Полезно для списков допустимых значений и для объектов конфигурации.

12. Что такое утверждение типа и когда оно опасно?

value as Type говорит компилятору доверять вам. Во время выполнения никакой проверки не происходит. Если вы ошиблись, ошибка проявится позже в виде падения. Предпочитайте сужение через проверку или type guard-функцию вместо утверждения.

Языковое поведение

13. В чём разница между null и undefined?

undefined означает, что значение никогда не присваивалось, а null — что «отсутствие значения» задано намеренно. При включённом strictNullChecks это разные типы. Для работы с ними используйте опциональную цепочку (a?.b) и nullish-оператор (a ?? b). В отличие от ||, оператор ?? срабатывает только для null и undefined, поэтому 0 и пустая строка сохраняются.

14. Что такое утверждение о ненулевом значении !?

value! сообщает компилятору, что значение не равно null или undefined. Как и as, это непроверяемое утверждение. Оно уместно в редких случаях, когда вы знаете больше компилятора, но проверка во время выполнения обычно надёжнее.

15. Что делает keyof и что такое typeof в позиции типа?

keyof T создаёт объединение имён свойств T. В позиции типа typeof x берёт тип значения, что избавляет от его повторения. Вместе keyof typeof obj даёт ключи объекта, определённого как значение.

16. Как enums соотносятся с union-типами?

Enums создают объект и значения во время выполнения. Объединение строковых литералов, например "idle" | "loading", стирается при компиляции и не требует дополнительного кода. Многие команды предпочитают объединения строковых литералов за простоту, а enums используют, когда нужен объект во время выполнения.

Инструменты и реальные проекты

17. Что делает tsconfig.json и какие опции важны?

Он указывает компилятору, какие файлы включать и как их проверять. Опции, о которых спрашивают на собеседованиях: strict, target (версия JavaScript для генерации), module и moduleResolution, noEmit (только проверка — часто, когда сборку выполняет другой инструмент), esModuleInterop и skipLibCheck.

18. Как типизировать что-то внешнее, например ответ API?

Типы исчезают во время выполнения, поэтому компилятор не может проверить, что возвращает сеть. Считайте данные unknown, а затем проверяйте их с помощью библиотеки схем или написанного вручную type guard, прежде чем использовать. Утверждение типа на разобранном JSON скрывает баги.

19. Как перевести проект с JavaScript на TypeScript?

Делайте это постепенно. Добавьте tsconfig.json с allowJs, переименовывайте файлы по одному, со временем включайте более строгие опции и сначала добавляйте типы на границах — например, в API-клиентах и общих утилитах. Избегайте переписывания всё сразу.

20. Что такое структурная типизация?

TypeScript сравнивает типы по форме, а не по имени. Если объект содержит поля, которые требует тип, он принимается, даже если никогда не объявлялся как этот тип. Это отличается от языков с номинальной типизацией, где важно объявленное имя.

Как готовиться

  1. Откройте playground или небольшой проект в strict-режиме и попробуйте каждый пример выше, включая те, что должны падать.
  2. Будьте готовы написать generic-функцию и размеченное объединение по памяти.
  3. Знайте, почему вы выберете unknown, а не any.
  4. Подготовьте одну историю о том, как вы типизировали что-то неудобное в реальном проекте.

Для дополнительной практики смотрите наши руководства по вопросам на собеседовании по Node.js, вопросам на собеседовании по Angular и вопросам на собеседовании по Python.

Практикуйтесь вслух и своими словами. Запись потом покажет, где вы растекались мыслью или упустили суть. Соблюдайте правила работодателя об использовании ИИ-инструментов на любом живом собеседовании или оценке.

Практикуйте свои ответы с YesToTheOffer

Репетируйте вслух, получайте ответы, построенные на основе вашего резюме, и просматривайте расшифровку afterward. 30 бесплатных минут, без подписки.

iOS & Android — Скоро
Цены