Вопросы на собеседовании: TypeScript-разработчик
100 реальных вопросов с образцовыми ответами и пояснениями для уровня Junior TypeScript-разработчик.
Смотреть пример резюме: TypeScript-разработчик →Тренировка флешкарточками
Интервальное повторение · Hunter Pass
Вопросы
TypeScript представляет собой язык со статической проверкой, который расширяет JavaScript типами и компилируется в JavaScript.
- Корректный синтаксис JavaScript, как правило, корректен и в TypeScript, поэтому переходить на него можно постепенно.
- Компилятор сообщает о многих ошибках типов до запуска кода.
- Браузеры и Node.js обычно выполняют сгенерированный JavaScript, а не исходный TypeScript напрямую.
Зачем это спрашивают: Интервьюер проверяет, понимаете ли вы TypeScript как слой разработки над JavaScript, а не как отдельную среду выполнения.
Статическая проверка типов означает, что TypeScript анализирует использование значений до запуска программы.
- Компилятор сопоставляет присваивания, аргументы и возвращаемые значения с объявленными или выведенными типами.
- Он может запретить операцию вроде вызова строкового метода у числа.
- Статические проверки устраняют целый класс ошибок, но не доказывают правильность всего поведения программы во время выполнения.
Зачем это спрашивают: Сильный ответ объясняет, когда выполняется проверка типов и где заканчиваются её гарантии.
Аннотация типа явно задаёт ожидаемый тип переменной, параметра, свойства или возвращаемого значения.
- Аннотация переменной ставится после её имени, например count: number.
- Она позволяет компилятору отклонить значения, не соответствующие заявленному контракту.
- Аннотации особенно полезны на границах системы или когда вывод типов не передаёт намерение достаточно ясно.
Зачем это спрашивают: Интервьюер оценивает, понимаете ли вы назначение аннотаций и не добавляете ли их там, где тип уже очевидно выводится.
Вывод типов позволяет TypeScript определить тип по окружающему коду без явной аннотации.
- Переменная, инициализированная значением 42, обычно получает тип number.
- Возвращаемый тип функции может быть выведен из значений, возвращаемых её ветками.
- Вывод типов сокращает повторения, сохраняя проверку на этапе компиляции.
Зачем это спрашивают: Интервьюер проверяет, умеете ли вы осознанно полагаться на вывод типов, а не аннотировать каждое значение.
Контекстная типизация выводит тип значения из места, где это значение используется.
- Тип параметра колбэка может быть выведен из метода или функции, которые принимают этот колбэк.
- Объектный литерал может проверяться относительно типа, ожидаемого переменной или аргументом.
- Такой контекст часто даёт полезные типы даже значению без собственных аннотаций.
Зачем это спрашивают: Сильный ответ показывает, что вывод может идти не только от присвоенного значения, но и от ожидаемого места использования.
Основные примитивные типы это string, number, boolean, bigint, symbol, null и undefined.
- TypeScript использует имена в нижнем регистре, например string, а не объектные обёртки вроде String.
- В JavaScript обычные целые числа и числа с плавающей точкой относятся к одному типу number.
- При включённой строгой проверке null значения null и undefined нужно обрабатывать явно.
Зачем это спрашивают: Интервьюер проверяет базовое знание типов и умение отличать примитивы от объектных обёрток.
Тип массива задаёт допустимый тип каждого элемента с помощью записи string[] или Array<string>.
- Обе формы описывают массив строк.
- Тип элементов с union, например Array<string | number>, разрешает в одном массиве элементы обоих типов.
- Тип элементов проверяется при чтении, добавлении и передаче значений в методы массива.
Зачем это спрашивают: Интервьюер оценивает, умеете ли вы правильно описывать однородные коллекции и массивы с union-типом элементов.
Кортеж представляет собой тип массива с известной длиной и отдельным типом для каждой позиции.
- Тип [string, number] требует строку на первой позиции и число на второй.
- Обычный number[] может содержать любое количество чисел без особого смысла у отдельных позиций.
- Кортежи подходят для небольших упорядоченных записей, а для крупных данных обычно понятнее именованные свойства объекта.
Зачем это спрашивают: Сильный ответ связывает кортеж с фиксированными позициями и выбирает его только тогда, когда порядок имеет смысл.
Объектный тип описывает имена свойств и типы значений, которые должен содержать объект.
- Свойство вроде name: string обязательно, если оно не отмечено как опциональное.
- Методы можно описывать свойствами с функциями или специальным синтаксисом методов.
- TypeScript проверяет структурную совместимость, поэтому важнее форма объекта, а не имя объявленного типа.
Зачем это спрашивают: Интервьюер проверяет понимание формы объектов и структурной системы типов TypeScript.
Interface даёт повторно используемое имя форме объекта.
- Он объявляет обязательные, опциональные, readonly-свойства и методы объектов или классов.
- Другие интерфейсы могут расширять его, добавляя или уточняя члены.
- Значение соответствует интерфейсу, если имеет совместимую структуру, даже без явного объявления этой связи.
Зачем это спрашивают: Сильный ответ описывает интерфейсы как повторно используемые структурные контракты, а не объекты времени выполнения.
Type alias присваивает повторно используемое имя любому выражению типа в TypeScript.
- Он может именовать форму объекта, union, intersection, кортеж, примитив или тип функции.
- Псевдоним не создаёт нового значения во время выполнения или отдельного номинального типа.
- Псевдонимы помогают составлять существующие типы в более понятные термины предметной области.
Зачем это спрашивают: Интервьюер проверяет, знаете ли вы, что псевдонимы именуют не только объекты и исчезают во время выполнения.
И interface, и type могут описывать форму объекта, но по-разному расширяются и ведут себя при повторных объявлениях.
- Интерфейсы расширяются через extends и могут объединяться при нескольких объявлениях с одним именем.
- Псевдонимы типов составляются через intersection и не могут быть заново открыты другим объявлением.
- Type также описывает union и кортежи, поэтому выбор обычно зависит от нужной возможности и соглашений проекта.
Зачем это спрашивают: Сильный junior-ответ называет практические различия и не утверждает, что один вариант всегда лучше.
Расширение создаёт интерфейс, содержащий члены одного или нескольких родительских интерфейсов.
- Дочерний интерфейс использует extends и может добавлять свои свойства или методы.
- Повторно объявленное свойство должно оставаться совместимым с унаследованным контрактом.
- Расширение удобно для выражения явной связи между родственными формами объектов.
Зачем это спрашивают: Интервьюер оценивает, умеете ли вы повторно использовать объектные контракты без дублирования членов.
Union-тип описывает значение, которое может относиться к любому из нескольких перечисленных типов.
- Члены объединяются вертикальной чертой, например string | number.
- До сужения доступны только операции, безопасные для каждого члена union.
- Union моделирует альтернативы точнее, чем ослабление значения до any.
Зачем это спрашивают: Интервьюер проверяет понимание как гибкости union, так и правила общих безопасных операций.
Intersection-тип объединяет несколько типов в один, который должен удовлетворять им всем.
- Члены объединяются амперсандом, например Identified & Timestamped.
- Для объектных типов результат обычно содержит обязательные свойства каждого члена.
- Конфликтующие требования к свойствам могут сделать часть или весь intersection невозможным для создания.
Зачем это спрашивают: Сильный ответ объясняет, что intersection требует выполнения всех контрактов, а не выбора одного из них.
Union принимает значение, подходящее хотя бы одному члену, а intersection требует соответствия каждому члену.
- string | number означает строку или число.
- Named & Auditable означает объект, который выполняет оба объектных контракта.
- Для union обычно сужают альтернативы, а у intersection можно использовать совместимые члены объединённых типов.
Зачем это спрашивают: Интервьюер проверяет, отличаете ли вы альтернативные формы от совмещённых требований.
Literal type представляет одно точное строковое, числовое или логическое значение вместо широкого примитивного типа.
- Тип 'pending' принимает только эту строку.
- Union литералов может задать закрытый набор, например 'pending' | 'done'.
- Точные значения помогают компилятору находить опечатки и неподдерживаемые варианты.
Зачем это спрашивают: Интервьюер проверяет, умеете ли вы моделировать конечные состояния точнее, чем обычной строкой.
Объявление const часто сохраняет литеральный тип примитива, а as const сохраняет литеральные значения во всём выражении.
- Переменная const со значением 'open' может получить литеральный тип 'open'.
- Свойства объекта обычно расширяются, потому что их значения можно переназначить.
- as const сохраняет узкие типы вложенных литералов и делает свойства объекта и элементы кортежа readonly.
Зачем это спрашивают: Сильный ответ отличает неизменяемую привязку переменной от const assertion для всего значения.
Опциональное свойство с ? может отсутствовать в объекте.
- При чтении его тип обычно включает undefined.
- Перед использованием как гарантированно существующего значения нужно проверить его наличие.
- Опциональное свойство не всегда равнозначно обязательному свойству, значение которого может быть undefined.
Зачем это спрашивают: Интервьюер проверяет безопасную работу с отсутствием и понимание разницы между пропущенным свойством и свойством со значением undefined.
readonly запрещает переназначать свойство или элемент коллекции через эту TypeScript-ссылку.
- readonly-свойство можно инициализировать, но нельзя напрямую присвоить ему новое значение позже.
- ReadonlyArray<T> запрещает изменяющие методы вроде push и splice.
- readonly действует на этапе компиляции и не замораживает JavaScript-объект во время выполнения.
Зачем это спрашивают: Сильный ответ называет защиту от изменений и её ограничение только этапом компиляции.
Закрытые вопросы
- 21
Что такое проверка лишних свойств у объектных литералов?
- 22
Как типизировать параметры и возвращаемые значения функций?
- 23
Чем отличаются опциональные параметры, параметры по умолчанию и rest-параметры?
resttypes - 24
Что означает возвращаемый тип void?
- 25
Что такое тип any и почему его следует использовать редко?
types - 26
Что такое тип unknown?
types - 27
Чем any отличается от unknown?
- 28
Что такое тип never?
- 29
Как ведут себя null и undefined при включённом strictNullChecks?
fundamentals - 30
Что такое сужение типов?
type-narrowing - 31
Как typeof сужает тип?
- 32
Как работает сужение по истинности значения?
type-narrowing - 33
Как работает сужение по равенству?
type-narrowing - 34
Как оператор in сужает union объектных типов?
union - 35
Как instanceof сужает тип?
- 36
Что такое дискриминированный union?
uniontype-narrowing - 37
Что такое пользовательский type predicate?
type-narrowing - 38
Что такое type assertion и чем он отличается от аннотации типа?
- 39
Что такое non-null assertion в TypeScript?
typescriptfundamentals - 40
Какую задачу решают дженерики в TypeScript?
typescriptgenerics - 41
Как generic-функция identity сохраняет информацию о типе?
generics - 42
Что такое ограничение дженерика?
generics - 43
Зачем generic-функции может понадобиться несколько параметров типа?
generics - 44
Как keyof используется с generic-типом объекта?
genericsadvanced-types - 45
Что такое enum в TypeScript?
typescriptenums - 46
Чем отличаются числовые и строковые enum?
- 47
Когда union строковых литералов может быть лучше enum?
unionenums - 48
Для чего используется tsconfig.json?
tsconfig - 49
Что делает настройка strict в tsconfig.json?
tsconfig - 50
Почему TypeScript не заменяет runtime-валидацию данных API?
validationapitypescript - 51
Как типизировать функцию, которая собирает полное имя пользователя из имени и фамилии?
- 52
Как типизировать асинхронную функцию, которая загружает одного пользователя, но может не найти результат?
async - 53
Хелпер принимает массив пользователей и callback, который выбирает подпись. Как типизировать callback?
callbacks - 54
Как типизировать необязательный размер страницы, чтобы внутри функции всегда использовать число?
types - 55
Как типизировать функцию, которая объединяет любое количество строковых сегментов пути?
joins - 56
Функция parseId принимает число или строку с числом. Как безопасно её типизировать и реализовать?
- 57
Как типизировать React-компонент UserCard с обязательным пользователем и необязательным компактным режимом?
reactcomponentstypes - 58
TypeScript сообщает, что у event.target нет свойства value в обработчике изменения input. Как исправить ошибку?
typescript - 59
Значение React state сначала пустое, а затем хранит User. Как типизировать useState?
reacthooks - 60
Как типизировать React-компонент layout, который принимает отображаемые дочерние элементы?
reactcomponents - 61
Как типизировать prop onSelect, который передаёт ID выбранного товара родительскому компоненту?
components - 62
Как сделать переиспользуемый компонент List, который сохраняет тип каждого элемента?
components - 63
Ключ колонки таблицы должен ссылаться на реальное свойство строки. Как типизировать этот ключ?
schema - 64
Как типизировать хелпер getProperty, чтобы возвращаемый тип зависел от выбранного ключа объекта?
- 65
Как типизировать переиспользуемый результат API, который может содержать разные типы данных?
api - 66
Функция должна принимать любое значение со свойством length. Как ограничить её generic-тип?
generics - 67
TypeScript отклоняет config[key] при переборе Object.keys(config). Как исправить ошибку?
typescriptiterationconfig - 68
Array.find возвращает User | undefined, но следующая строка ожидает User. Как исправить ошибку?
fundamentals - 69
document.querySelector может вернуть null. Как безопасно обновить выбранный элемент?
queriesfundamentals - 70
В блоке catch ошибка имеет тип unknown. Как безопасно получить сообщение?
- 71
Значение имеет тип User | Admin, а permissions есть только у Admin. Как безопасно прочитать permissions?
- 72
После фильтрации null TypeScript всё ещё сохраняет null в типе массива. Как исправить filter?
typescriptfundamentals - 73
Как представить состояния загрузки, успеха и ошибки API без необязательных полей повсюду?
types - 74
Как заставить switch по union статусов выдавать ошибку типов при добавлении нового статуса?
union - 75
Почему проверка typeof value === 'object' всё ещё может сломаться при чтении полей и как её исправить?
- 76
API возвращает объект пользователя или объект с полем error. Как различить эти варианты?
api - 77
Как написать type guard для значения unknown, которое должно быть User?
type-narrowing - 78
Проверка if (count) ошибочно считает ноль отсутствующим. Как сузить count: number | undefined?
fundamentals - 79
Как безопасно показать город из user.profile.address, если каждое вложенное поле может отсутствовать?
- 80
fetch возвращает JSON из внешнего сервиса. Как сохранить типобезопасность ответа?
type-safety - 81
Как типизировать обёртку над fetch, которая обрабатывает HTTP-ошибки и успешный JSON?
http - 82
Backend иногда присылает avatarUrl: null, но frontend-тип указывает string. Как исправить несоответствие?
fundamentals - 83
API использует поля в snake_case, а приложение в camelCase. Как типизировать преобразование?
api - 84
Как типизировать PATCH-запрос, который обновляет только часть полей User?
- 85
Как создать публичный тип пользователя без passwordHash и внутренних заметок?
passwords - 86
Как типизировать словарь подписей, в котором обязан присутствовать каждый OrderStatus?
- 87
Сгенерированные OpenAPI-типы больше не совпадают с развёрнутым API. Что вы будете делать?
openapideployment - 88
Как типизировать обработчик отправки React-формы и безопасно прочитать значения input?
reactforms - 89
Как типизировать React ref для input, который изначально не смонтирован?
react - 90
React context по умолчанию равен null. Как не заставлять каждого потребителя помнить о проверке null?
reactfundamentals - 91
Как типизировать переиспользуемое поле формы, имя которого обязано быть ключом значений формы?
forms - 92
Как типизировать actions редьюсера, чтобы каждый action нёс правильный payload?
- 93
TypeScript выводит {} для аккумулятора reduce, который группирует пользователей по ролям. Как это исправить?
typescriptadvanced-types - 94
Как сохранить отдельный тип каждого результата при одновременном ожидании разных промисов?
asyncpromises - 95
JSON.parse может создать значение любой формы. Как безопасно загрузить настройки приложения из localStorage?
- 96
У JavaScript-пакета нет деклараций типов. Как подключить его, не превращая всю функцию в any?
javascript - 97
Тип сторонней библиотеки говорит, что значение всегда string, но runtime-логи показывают null. Как поступить?
dependenciesfundamentals - 98
Как типизировать фиксированный набор названий тем без широкого string?
- 99
В вызове компонента есть опечатка в prop, но assertion скрывает ошибку. Как это исправить?
components - 100
Вы получили TypeScript-ошибку в незнакомом коде. Что сделаете до добавления cast?
typescript