14 KiB
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 | Практика не обещает массовое переименование; в маршруте сохранены соседние JavaScript-модули |
| TypeScript-специфичные конструкции не становятся runtime-проверкой после компиляции | TypeScript Handbook: Migrating from JavaScript, TypeScript 3.5 release notes | В механизме type alias отделён от исполняемого normalizer; сетевой payload не объявлен проверенным только из-за interface |
allowJs принимает JavaScript-файлы рядом с TypeScript, что подходит для поэтапного переноса |
TSConfig: allowJs | Конфигурация fixture держит allowJs и noEmit; она не меняет format модулей и output production-сборки |
checkJs выдаёт diagnostics для JavaScript; локальный @ts-check позволяет начать с одного файла |
TSConfig: checkJs | В practice и field @ts-check стоит в одном boundary-файле, а не выдаётся за включение проверки всего legacy-дерева |
TypeScript 3.5 уже содержит нужную для примера эпоху: проверку JavaScript, unknown, type predicates и релизные изменения вокруг generic checking |
TypeScript 3.5 release notes | Нет позднего синтаксиса, 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 этого не
подменяют.