Галоўная / Артыкулы / TypeScript 7.0 перахоўвае кампайляр на Go для адпаведнай швальнасці.

TypeScript 7.0 перахоўвае кампайляр на Go для адпаведнай швальнасці.

TypeScript 7.0 переносіць tsc у Go з паралельнымі пераглядачамі, новымі стандартнымі настройкамі tsconfig, шаблоннымі літераламі Unicode, стрэльнейшай аналізайом коду на JS, а таксама тымчасовым прыводам у програмнай API.

1086 слоў

Прыблызна чатырнацца гадоў кампайляр TypeScript могаў сам сабе стварыць. tsc быў версіяй TypeScript, якая кампайлявалася у JavaScript і працавала на Node. Колі колькасць коду ў рэпозытарыях вырасла да мільйоноў лінак, такі спосаб працы стаў вузкам местам.

У TypeScript 7.0 зменілася мова-хост. Кампайляр і служба обработкі мовы перашлі з TypeScript у Go. Microsoft апісвае гэтыя змены як перенесенне, а не перапісву: структура перакантролювання типаў застаецца такой жа, як у версіі 6.0, але выконанне выкалываецца як натыўны код з паралельнай працэю за дапамогою спяльванага памяці. У публікуемых порэваннях часта фіксуецца прыблызна 10× паўтарэнне скорасці у пораўнанні з TypeScript 6.0.

Адны з часта цітаваных прыкладоў паказвае, насколькі рэальныя ўлучанні. Перакантролюванне коду ў VS Code — прыблызна 1,5 мільйона лінакаў TypeScript — зменілася з прыблызна 77,8 секунд на адпаведны час прыблызна 7,5 секунд.

Якща ранейшыя публікацыі вжывалі кодавое назва Project Corsa (дзе старыя дрэвы JavaScript мелі прозвішча Strada), то гэты выпуск — яго фінальная версія.

Чаму самэў Go, і чаму пераклад у іншы язык?

У гласных думках часта называлі Rust. Выбрали Go, таму што ён падходзіў па структуре да існуючага кампайляра: моцныя графы, сборчык сметлівасці та цыклічныя структуры, якія важка адтворыць з нуля. Гэта сумяшанне парадоксальнаў можлівасць лінія-за-лініяю перакладу.

Формат перакладу мае большое значэнне, чым сам язык. Зберагчы архітектуру, мы застаўілі правіла. Проекты, якія вже пераглядаюць типы пад версіяй 6.0 з увёмканым stableTypeOrdering і без ignoreDeprecations, должны атрымаць тыя ж рэзультаты пад версіяй 7.0 — проста швэдзейшы двайнок, а не іншая система типаў.

Спачатку был адаптаваны тэсты працы системы пад час вырабаткі. За больш адзін год порт працаваў на велікіх системах у такіх сервісах, як Bloomberg, Figma, Google, Slack, Notion і Vercel, прычаму да гэтага этапу.

Праўія паралелізацыя

Раней пропускна здатнасць была обмежана адной нейтварнай задачай Node. Натыўныя працоўнікі усунулі гэтае обмежэння. У версіі 7 робота па аналізу, перакантроле і выдачы дадзеных стала распадацца на часткі, а таксама былі даданы флагі:

  • --checkers задае колькісць паралельных працоўнікаў для перакантроле типаў
  • --builders паралелізуе процесы стварэння проектаў і стакоў у монорепозітарыях разам з --checkers
  • --singleThreaded з’едынае всю роботу ў аднам ядре для дэбагу і вызначэння базовых часоў

Робота па аналізу/выдачы дадзеных за кожны файл залежыць ад размеру репазітарыя і ступеня модулярнасці; маленькія прыложэння з адным файлам отрымаюць меншы эфект.

Режым аблявання таксама быў перабудаваны. Апыткі збору данных спрацоўвалі CPU ў вельмі большых дрэвах node_modules; выкарыстоўванне механізма аблявання Parcel у языку Go зменшае гэтыя витраты і дазволяе быстрей реагаваць на змяны.

Змены ў налашчаннях, якія створуюць проблемы для команд

TypeScript 6.0 служыў мостам: новыя стандартныя налашчанні та забойваныя функцыі паказваліся як апавешчэння. 7.0 ператварае іх у серьязныя бяды. Команды, якія вже перайшлі на 6.0, зробілі большую частку работы. Перехад з 5.x адразу на 7.0 вымагае часу на практычную налаштовку tsconfig.json.

Серьязныя змены стандартных налашчанняў:

  • strict ўвімкнуты, якщо толькі не зменены
  • module налаштаваны на esnext, тады як target выбірае найновейшую стабільную версію ECMAScript, якая не ўключае esnext
  • noUncheckedSideEffectImports ўвімкнуты за замовчанням
  • libReplacement выключаны за замовчанням
  • stableTypeOrdering застаецца актываўным.
  • rootDir пачынаецца з ./.
  • types пачынаецца як порожняй спіс.
  • У дасведчэннях rootDir і types называюцца тымі элементамі, з якімаі команды сталкнуцца першыя — і тымі, якія лёгкая ў выправленні.

    Якщо tsconfig.json знаходзіцца вышэй за папку src, явна задаце rootDir, каб структура выходных дакументаў засталая звычайной:

    {
      "compilerOptions": {
        "rootDir": "./src"
      },
      "include": ["./src"]
    }
    

    Паколькі types больш не автаматычна імпортуе все, што знаходзіцца пад node_modules/@types, указаце тое, што вам патрэбна:

    {
      "compilerOptions": {
        "types": ["node", "jest"]
      }
    }
    

    Параметры, якія раней толькі паветарылі, тепер спрачынаюць серйозныя проблемы (яны перестаюць выканаць які-лебе корыстныя задачы):

    • Адмініструйце target: es5 і downlevelIteration.
  • Заменіце старыя значэння moduleResolution (node, node10, classic) на nodenext або bundler
  • Зняце режымы module, такія як amd, umd, systemjs і none, і заменіце их на esnext або preserve
  • Адыянуце параметр baseUrl і задаўце paths абсалютна ўжо да корню проекту
  • Не зменяйце значэння esModuleInterop / allowSyntheticDefaultImports на false
  • Спрыяйце таму, каб параметр alwaysStrict быў увесь час уваўлечаны
  • Якща пасля гадоў без перагледу параметр moduleResolution яшчэ залишаецца на старым значэнні node, то гэты файл ёсць спісам пунктав для міграцыі.

    Unicode у типах з літераламі шаблона

    Тэперыць типы шаблонных літэралав адпавядаюць код-пунктам Unicode, а не код-едыніцам UTF-16:

    type HeadTail<S> = S extends `${infer Head}${infer Tail}` ? [Head, Tail] : never;
    
    type Result = HeadTail<"😀abc">;
    // In 7.0:      ["😀", "abc"]
    // Previously:  ["\ud83d", "\ude00abc"]
    

    Старэйшыя кампайляры моглі розбіваць пару заместнікаў эмодзі. Гэта падражнала спосаб адчыслення індэксаў у JS і рэдка падтрымвала намеры аўтара. Тепер ітерацыя адбываецца па код-пунктам, як і у for...of та [...str]. Інструменты, якія намеравана лічылі UTF-16 едыніцы, будуць нефункцыйнальныя; усе іншыя будуць атрымляць тое поведзенне, якого чакалі.

    Строгейшая аналіза JavaScript

    Праблемы пераказу .js раней падтрымвалі больш JSDoc та ідыомы перыяду Closure. Выпуск 7 праглыбляе гэты крок у напрамку правілаў .ts:

    • Месцы, якім патрэбныя типы, адхоўляюць простыя значэнні — лепш выкарыстоўваць typeof someValue
    • @enum / @class тыятрэць спецыяльнага адносу; трэба заявіць рэальны клас або выкарыстоўваць @typedef
    • Просты ? не прыймаецца як тип — лепш выкарыстоўваць any
  • Асэрцыі, якія заканчваюцца !, не падтрымваны — трэба явна запісваць T
  • Старыя форматы function(string): void заменяюцца на (s: string) => void
  • Прасоць у програмнай API

    У версіі 7.0 яшчэ не ёсць стабільнай програмнай API. Таму бібліятэкі, якія включаюць кампайляр — інтеграцыя ESLint з TypeScript, ts-morph, ручнае стварэнне трансформероў, а таксама дапаможнікі для рэдагування шаблонаў у Vue, Svelte, Astro, MDX чыя Angular — яшчэ не можу цалком перайсці на новую структуру. Microsoft адносіцца да гэтага прасоцу як да тымчасовага і плануе завершыць розробку API у версіі 7.1 і пасляеўных выданнях.

    Тым часам, выкорыстоўваюце версію 7.0 там, дзе не патрэбны плагіні language-server. Команды Angular, напрыклад, можаць запускаць tsc з версіі 7.0 для шырокага адзначэння проблем у проекте за дапамою CLI, адначасова заставаючы версію 6.0 у рэдагары. Пакет для сумеснасці @typescript/typescript6 апранае бінарны файл tsc6 і занову выклікае API версіі 6.0, тады яны можаць сусістаць адночасова:

    {
      "devDependencies": {
        "typescript": "npm:@typescript/typescript6@^6.0.0"
      }
    }
    

    Чы гэта трэба апдэйтаваць?

    Якщо вы вжо на TypeScript 6.0, міграцыя ўскоранае і дае вялікую выгоду: пасля налаштавання калька tsconfig вы атрымаеце шырэйшыя пераканальнікі CI і быстрейшы старт рэдагара. У болей старых версіях існуюць справжнія проблемы з сумеснасцю, але практычна ўсія з іх вже былі аанунцаваны.

    Заўважкайце кандыдата на выпуск сёньня:

    npm install -D typescript@rc
    

    Для рэдагароў сёньня дадатак VS Code падтрымлівае LSP, а інтеграцыя з самим VS Code расширваецца. Visual Studio выклікае версію 7.0 у адкрытым працоўным месца без додатковага крока інсталляцыі.

    Адміністратары кажу, что выпускі новых функцыйяў знова будуць адбывацца за звычным мнагамесячным ритмам, і прыпускаецца, што версія 7.1 заполні цю прасоўку ў API для вбудоввання.

    Аб’ектыўны рэзультат: звычныя правілы TypeScript, якія працуюць як натыўны код.