# P20 · октябрь 2019 · миграция JavaScript на TypeScript — тройное ревью Статус: **принят в публикационный слой 31 июля 2026 года**. Registry применяет три revision по стабильным slug и сохраняет дату и автора базового архива: - editorial-2019-10-practice-typescript-migration; - editorial-2019-10-mechanism-typescript-migration; - editorial-2019-10-field-typescript-migration. Модуль экспортирует ровно три revision без полей date и author. При прямом вызове с --print-revisions он печатает только JSON, совпадающий с import-safe export. В статьях типы, fixture и метрики показаны как методы проверки; ни один вымышленный production-результат не выдан за измерение. ## Проход 1. Факты и техника — пройдено | Утверждение или решение | Первичный источник | Проверенная граница | | --- | --- | --- | | JavaScript-синтаксис допустим в TypeScript, поэтому файл можно переносить постепенно, а не одномоментно | [TypeScript Handbook: Migrating from JavaScript](https://www.typescriptlang.org/docs/handbook/migrating-from-javascript.html) | Практика не обещает массовое переименование; в маршруте сохранены соседние JavaScript-модули | | TypeScript-специфичные конструкции не становятся runtime-проверкой после компиляции | [TypeScript Handbook: Migrating from JavaScript](https://www.typescriptlang.org/docs/handbook/migrating-from-javascript.html), [TypeScript 3.5 release notes](https://devblogs.microsoft.com/typescript/announcing-typescript-3-5/) | В механизме type alias отделён от исполняемого normalizer; сетевой payload не объявлен проверенным только из-за interface | | allowJs принимает JavaScript-файлы рядом с TypeScript, что подходит для поэтапного переноса | [TSConfig: allowJs](https://www.typescriptlang.org/tsconfig/allowJs.html) | Конфигурация fixture держит allowJs и noEmit; она не меняет format модулей и output production-сборки | | checkJs выдаёт diagnostics для JavaScript; локальный @ts-check позволяет начать с одного файла | [TSConfig: checkJs](https://www.typescriptlang.org/tsconfig/checkJs.html) | В practice и field @ts-check стоит в одном boundary-файле, а не выдаётся за включение проверки всего legacy-дерева | | TypeScript 3.5 уже содержит нужную для примера эпоху: проверку JavaScript, unknown, type predicates и релизные изменения вокруг generic checking | [TypeScript 3.5 release notes](https://devblogs.microsoft.com/typescript/announcing-typescript-3-5/) | Нет позднего синтаксиса, satisfies, optional chaining, Zod, современных стратегий Node module resolution или заявлений зрелости 2027 года | ### Честная граница фикстур Код normalizer проверяет учебный объект Member и предназначен для трёх контролируемых входов: валидный объект, объект без email и объект с чужим status. Он показывает, где runtime-код должен остановить неясный payload. Фикстура не вызывает реальный API, не измеряет скорость сборки и не подтверждает ответ конкретной сетевой библиотеки. Конфигурация с noEmit — безопасный первый режим проверки, а не совет заменить существующий delivery pipeline. Если конкретный проект генерирует JavaScript через tsc, интегратор обязан отдельно сопоставить target, module, output path и реальную production-команду. Этот риск в статьях назван ограничением, а не скрыт обещанием «переход пройдёт безболезненно». Вердикт прохода: **пройден**. Технические утверждения привязаны к официальным источникам TypeScript, а свойства, зависящие от конкретного проекта, оставлены явными задачами проверки. ## Проход 2. Редактура и голос М2 / 2019 — пройдено | Ревизия | Симптом и цена в начале | Главный вопрос | Практический артефакт и ограничение | | --- | --- | --- | --- | | Практика | Массовый rename создаёт any и останавливает выпуск; цена — длинная ветка без полезной проверки данных | Как начать миграцию с границы и сохранить build | tsconfig fixture, JSDoc normalizer, таблица границ и выпускной маршрут; процент .ts не выдан за качество | | Механизм | Файл уже .ts, но неверный payload доходит до экрана; цена — место ответственности скрыто за any | Почему типы исчезают в runtime и где ставить проверку | сравнение исходника и JavaScript, normalizer unknown → Member, таблица ролей; статический анализ не выдан за runtime-защиту | | Полевой разбор | Legacy transport отдаёт response.body напрямую; цена — неясный откат и риск сломать delivery | Как перенести один поток без массового rewrite | автономная fixture transport → normalizer → screen и четыре gate; нет заявления о запуске реального сервера | - Первые два абзаца каждой статьи называют симптом, проблему и стоимость неверного маршрута. Дальше текст держит цепочку: симптом → причина → проверка → действие → ограничение. - Речь короткая и техническая: вместо общих оценок названы allowJs, checkJs, noEmit, unknown, any, normalizer, contract fixture, type-check и build gate. - Автор соответствует М2 / 2019: он уже связывает frontend-код, delivery и API-границу, но не приписывает себе поздние практики платформенной команды, SLO, современную схему валидации или зрелую организационную программу миграции. - Три текста не дублируют друг друга: практика задаёт маршрут, механизм разбирает исчезновение типов и роль any, полевой разбор собирает минимальную выпускную партию. - Объём, число разделов, таблица с caption/thead, код, упорядоченный маршрут, figure с alt/caption и два или больше источника подлежат независимой автоматической проверке draft gate. Вердикт прохода: **пройден**. Тексты сохраняют практический голос автора 2019 года и не подменяют решение эффектными обещаниями. ## Проход 3. Визуал и выпуск — пройдено в пределах автономного пакета - typescript-migration-lane-2019.svg показывает четыре малых шага: baseline выпуска, границу данных, локальный @ts-check и один TypeScript-модуль; выпускные gate вынесены в нижний блок. Визуал не предлагает переписать всё дерево файлов. - typescript-migration-type-boundary-2019.svg противопоставляет нормальный путь unknown → runtime normalizer → Member красному обходу через any. Это уточняет границу ответственности, а не дублирует таблицу из статьи. - typescript-migration-release-gates-2019.svg отделяет contract fixture, type-check, существующий build и smoke. Четыре карточки прямо показывают, что один успешный gate не доказывает остальные. - У всех SVG есть title, desc, role="img" и aria-labelledby. В статьях предусмотрены самостоятельные содержательные alt-тексты и figcaption. SVG не содержат JavaScript, внешних URL, foreignObject или растровых data URI. - Независимый мобильный preflight отрисовал каждый SVG через Sharp в PNG шириной 375 px. Первый вариант двух схем содержал слишком мелкие вторичные подписи. Их заменили на вертикальные композиции с короткими подписями; повторный рендер не показал обрезания, наложения или горизонтального выхода. Это проверка статичных схем, а не browser-review страницы. - После подключения registry строгий аудит подтвердил три revision, а production build сгенерировал 374 статические страницы. Реальный browser review остаётся отдельной проверкой поведения и не заявлен как выполненный. ### Фактические проверки Запускаются следующие независимые проверки:
node --check web/scripts/upgrade-2019-10.mjs
cd web && npm run audit:draft -- scripts/upgrade-2019-10.mjs
xmllint --noout \
  web/public/assets/editorial/2019/typescript-migration-lane-2019.svg \
  web/public/assets/editorial/2019/typescript-migration-type-boundary-2019.svg \
  web/public/assets/editorial/2019/typescript-migration-release-gates-2019.svg
Результат независимого запуска 31 июля 2026 года: | Проверка | Результат | | --- | --- | | node --check | PASS, синтаксис модуля корректен | | --print-revisions и import-safe export | PASS внутри draft gate: stdout — только JSON, export совпадает с CLI и содержит ровно три revision | | npm run audit:draft -- scripts/upgrade-2019-10.mjs | PASS: 9 756 / 9 495 / 10 347 знаков основного текста; у каждого текста есть проблема в начале, пять или больше разделов, figure, таблица, код, маршрут и источники | | xmllint --noout для трёх SVG | PASS, XML корректен | | Strict audit после подключения registry | PASS: 9 756 / 9 495 / 10 347 знаков; по одному figure и table, по два code example | | npm run build | PASS, code 0, 374 статические страницы | | Scope/self-review | PASS: в revision нет date/author; в SVG нет script, foreignObject, внешних ссылок или data URI; articles.json не перезаписан | Выпусковой вердикт: **тройное ревью пройдено, пакет принят к публикации**. articles.json не менялся; registry заменяет только редакционные поля по стабильному slug. Поведение на реальной странице в выбранном браузере нужно проверить отдельно: production build и raster preflight этого не подменяют.