Senior: питання на співбесіді з теми «Конфігурація й інструменти»
Питання з реальних співбесід з відповідями: Laravel і PHP, бази даних, JavaScript і фронтенд, Git, Docker, API, безпека й архітектура. Тими самими темами, що й тести.
4 питання
TypeScript 7 - компілятор, переписаний з TypeScript на Go. Порт робили максимально близько до оригіналу, тож перевірка типів дає ті самі результати, а виграш - у швидкості: нативний код і багатопотоковість.
Що це дає на практиці:
- повна збірка у 8-12 разів швидша: за даними команди TypeScript, перевірка кодової бази VS Code - 10,6 с замість 125,7 с;
- редактор: проєкт відкривається й показує першу помилку за секунду-дві замість десятків секунд;
- пам'ять - зазвичай менше, ніж у TypeScript 6;
- новий режим
--watchна основі файлового спостерігача з Parcel, портованого на Go.
Нові прапорці паралелізму:
--checkers N- кількість паралельних перевіряльників типів (за замовчуванням 4). Більше - швидше на потужних машинах, але більше пам'яті; на слабких CI-раннерах варто зменшити;--builders N- паралельна збірка проєктів у--build(монорепозиторії). Множиться з--checkers:4 × 4- до 16 перевіряльників одночасно;--singleThreaded- вимкнути паралелізм (налагодження, обмежені середовища).
Різна кількість --checkers у рідкісних випадках може дати різні результати, залежні від порядку, - тому команді варто зафіксувати одне значення для всіх середовищ.
Що потребує уваги при переході:
- TypeScript 7 бере значення за замовчуванням з 6.0 (
strict,types: [],rootDir: ".") і робить помилками все, що 6.0 оголосив застарілим:baseUrl,moduleResolution: node10,target: es5,module: amd/umd,esModuleInterop: falseта інше. Рекомендований шлях - спершу перейти на 6.0 і прибрати всі попередження; - немає програмного API в 7.0 - його обіцяють у 7.1. Інструменти, що імпортують
typescriptяк бібліотеку (typescript-eslint, частина плагінів збирачів), працюють через пакет сумісності@typescript/typescript6, встановлений поряд через псевдонім npm. Тодіtsc- це TypeScript 7, а інструменти бачать API 6.0; - JSDoc у JavaScript-файлах аналізується ближче до
.ts- деякі старі шаблони перестали розпізнаватися; - шаблонні рядкові типи тепер працюють з кодовими точками Unicode, а не з половинками сурогатних пар.
Що лишилося незмінним: мова, синтаксис і правила перевірки. Код, що компілюється в 6.0 без попереджень, компілюється в 7.0 так само.
Сучасний Node.js виконує .ts-файли без окремої збірки: він замінює анотації типів пробілами (type stripping) і запускає те, що лишилося.
node scripts/import-vacancies.ts
Зняття типів увімкнене за замовчуванням з Node.js 22.18 / 23.6 і стабільне з 24.12 / 25.2. Перевірки типів при цьому немає - помилки типів не зупинять запуск.
Обмеження - лише «стиранний» синтаксис. Node.js не генерує код, він тільки прибирає типи. Конструкції TypeScript, що створюють JavaScript, не підтримуються:
enum;namespaceз кодом під час виконання;- параметри-властивості в конструкторі (
constructor(private repo: Repo)); import x = require(...)і псевдоніми імпорту;- декоратори (поки їх немає в самому JavaScript).
Прапорець --experimental-transform-types, що їх перетворював, у Node.js 26 прибрали.
erasableSyntaxOnly (з TypeScript 5.8) змушує tsc повідомляти про такі конструкції заздалегідь:
enum Status { Draft, Published } // error TS1294: This syntax is not allowed when 'erasableSyntaxOnly' is enabled
Замість enum - об'єкт з as const і тип-об'єднання; замість параметрів-властивостей - звичайні поля.
Рекомендовані Node.js налаштування tsconfig.json:
{
"compilerOptions": {
"noEmit": true,
"target": "esnext",
"module": "nodenext",
"rewriteRelativeImportExtensions": true,
"erasableSyntaxOnly": true,
"verbatimModuleSyntax": true
}
}
Інші особливості:
- розширення обов'язкові:
import { x } from './utils.ts'; import typeдля типів - інакше Node.js залишить імпорт і впаде (томуverbatimModuleSyntax);tsconfig.jsonігнорується:pathsне працюють - замість них subpath imports уpackage.json("#/*");- файли в
node_modulesне виконуються - пакети мають публікуватися як JavaScript; .tsxне підтримується.
Коли це доречно: скрипти, утиліти, інструменти розробки, невеликі сервіси - там, де збірка була зайвим кроком. Для повної підтримки TypeScript (paths, enum, JSX) - інструменти на кшталт tsx або звичайна збірка.
Великий кодовий масив в одному tsconfig.json перевіряється цілком при кожній зміні. Project references ділять його на окремі проєкти з явними залежностями, і TypeScript перевіряє лише змінене та залежне від нього.
Структура:
// tsconfig.json (корінь) - лише посилання
{
"files": [],
"references": [
{ "path": "./packages/shared" },
{ "path": "./packages/web" },
{ "path": "./packages/admin" }
]
}
// packages/shared/tsconfig.json
{
"compilerOptions": {
"composite": true,
"declaration": true,
"rootDir": "./src",
"outDir": "./dist"
}
}
// packages/web/tsconfig.json
{
"references": [{ "path": "../shared" }]
}
tsc -b # зібрати всі проєкти в порядку залежностей
tsc -b --watch
composite: true - вимоги до проєкту, на який посилаються: генерація .d.ts, явний rootDir, усі файли в include. Залежний проєкт бачить лише оголошення (.d.ts) залежності, а не її вихідний код - тому перевірка швидша.
incremental - зберегти результати попередньої перевірки у файлі .tsbuildinfo і наступного разу перевіряти лише змінене. Для composite увімкнено автоматично.
Що це дає:
- швидкість: зміна в
adminне змушує перевірятиweb; - межі: пакет не може імпортувати з іншого, якщо на нього немає посилання, - архітектура перевіряється компілятором;
- різні налаштування для частин: код браузера з
lib: ["dom"], конфіги й сервер - з типами Node.js. Саме так шаблон Vite ділить проєкт наtsconfig.app.jsonіtsconfig.node.json.
TypeScript 7 збирає незалежні проєкти паралельно (прапорець --builders), тож виграш від поділу ще більший. Обмежувач - граф залежностей: проєкт збирається лише після тих, від яких залежить. Опція isolatedDeclarations дає змогу генерувати .d.ts без перевірки типів залежностей і розпаралелити й це.
Пастки:
rootDirз TypeScript 6.0 за замовчуванням - каталог зtsconfig.json. Якщо вихідні файли вsrc/, аrootDirне вказано, результат опиниться вdist/src/...замістьdist/...;- застарілі
.d.ts: редактор може показувати старі типи залежності, доки її не перезібрано; skipLibCheck(пропустити перевірку.d.ts) теж помітно пришвидшує збірку, але ховає помилки в оголошеннях власних пакетів - його вмикають свідомо.
TypeScript 6.0 - перехідний реліз: останній на старому компіляторі, який готує проєкти до TypeScript 7. Він змінює значення за замовчуванням і оголошує застарілими опції, які в 7.0 стали помилками.
Нові значення за замовчуванням:
| Опція | Було | Стало |
|---|---|---|
strict |
false |
true |
module |
залежно від target |
esnext |
target |
es5 |
останній стабільний стандарт (es2025) |
types |
усі @types/* |
[] |
rootDir |
спільний каталог вихідних файлів | каталог з tsconfig.json |
noUncheckedSideEffectImports |
false |
true |
Найчастіші проблеми після оновлення:
- «Cannot find name 'process'» / «describe» - додати
"types": ["node", ...]; - результат збирається в
dist/src/index.jsзамістьdist/index.js- вказати"rootDir": "./src"; - нові помилки строгості - або виправляти, або явно
"strict": falseяк тимчасовий крок.
Видалено в TypeScript 7 (у 6.0 - попередження, які можна приглушити "ignoreDeprecations": "6.0"):
baseUrl- шляхи вpathsтепер відносно каталогу конфігу з префіксом./;moduleResolution: node(node10) іclassic- замінити наbundlerабоnodenext;target: es5іdownlevelIteration- найнижча цільes2015; для ES5 - зовнішній компілятор;module: amd,umd,systemjs,noneіoutFile;esModuleInterop: false,allowSyntheticDefaultImports: false,alwaysStrict: false;- ключове слово
moduleдля просторів імен (лишеnamespace) іassertsв імпортах (лишеwith); - передача файлів у
tscу каталозі зtsconfig.jsonбез--ignoreConfig.
Рекомендований порядок:
- оновитися до TypeScript 6.0 і виправити всі попередження про застарілі опції (не приглушувати
ignoreDeprecationsнадовго - у 7.0 це не спрацює); - частину змін (
baseUrl,rootDir) робить автоматично експериментальний інструментts5to6; - перевірити з прапорцем
stableTypeOrdering- у 7.0 він увімкнений і незмінний; з ним 6.0 дає ті самі результати, що й 7.0; - перейти на TypeScript 7, а для інструментів, що потребують API (
typescript-eslint), лишити поряд@typescript/typescript6.
Чому ці зміни корисні: явний types пришвидшує перевірку на 20-50%, а видалені опції здебільшого ховали помилки (TypeScript «бачив» імпорти, які не працювали під час виконання).