Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти Інструменти Події
Інше
Про нас Реклама

Навіщо isolatedModules і verbatimModuleSyntax і чому їх вимагають збирачі?

Vite, esbuild, oxc, swc і Node.js перетворюють TypeScript на JavaScript по одному файлу і без перевірки типів - просто прибирають анотації. Це швидко, але такий інструмент не бачить інших файлів проєкту. Частина конструкцій TypeScript без знання інших файлів перетворюється неправильно.

Головна проблема - імпорт типу:

// types.ts
export type User = { id: number };

// app.ts
import { User } from './types';

Компілятор TypeScript знає, що User - тип, і прибере імпорт. Інструмент, що бачить лише app.ts, цього не знає: залишить import { User } from './types' - і в браузері помилка «The requested module does not provide an export named 'User'».

isolatedModules - TypeScript попереджає про код, який неможливо безпечно перетворити по одному файлу: реекспорт типу без type, const enum між файлами, файли без імпортів і експортів.

verbatimModuleSyntax - строгіший і простіший підхід: імпорти лишаються в JavaScript рівно так, як написані, крім позначених type. Тому тип треба явно позначити:

import type { User } from './types';
import { fetchUser, type UserFilter } from './api';

З опцією TypeScript видасть помилку на import { User }, якщо User - лише тип.

Що обрати: у сучасних проєктах - verbatimModuleSyntax: true. Він робить поведінку однаковою для tsc, збирачів і Node.js і замінює старіші importsNotUsedAsValues і preserveValueImports. Шаблони Vite вмикають його за замовчуванням.

Наслідки, які варто знати:

  • імпорти з побічними ефектами зберігаються: import './styles.css' нікуди не зникне;
  • import type не виконує модуль - якщо вам потрібен побічний ефект модуля, потрібен звичайний імпорт;
  • з CommonJS опція змушує писати import x = require('...') для CommonJS-виводу - у кодовій базі на ES-модулях це не відчувається;
  • лінтер (@typescript-eslint/consistent-type-imports) автоматично виправляє імпорти, тож перехід на велику кодову базу - один прогін автовиправлення.

Зв'язок з Node.js: вбудоване виконання TypeScript у Node.js теж прибирає лише імпорти з type - без verbatimModuleSyntax такі помилки виявляться лише під час запуску.

Докладніше в документації: Опція verbatimModuleSyntax

Схожі питання