Галоўная / Артыкулы / TypeScript 6 і 7: розумнейша адгадка даных, пасля чаго — перапісвання на мове Go.

TypeScript 6 і 7: розумнейша адгадка даных, пасля чаго — перапісвання на мове Go.

Дазвольце даклэ научыцца, як TypeScript 6 усунуў прасоці ў адгадванні ключоў і модернізаваў стандартныя настройкі, стварыўшы падставу для цэлыснага перапісвання кампайляра у TypeScript 7 на мове Go.

1255 слоў

У аптэкцы TypeScript нешта часоў практычна развиваецца ў двух напрамках, і яны разам расказваюць адну історыю: мова становіцца як болей розумнай, так і болей быстрой. TypeScript 6, які выйшаў як фінальная версія, напісаная на традыцыйным компайлеры на базе JavaScript перад вялікімі архітэктурнымі змянамі, быў спрытаваны на вылечэнне давняых проблем з інференцыяй та модэрнаізацыю стандартных насталоў. TypeScript 7 жа здзейсніў болей радыкальны крок — перапісаў сам компайлер на мове Go, ставячы прыорітэт на высокую скорасць, а не на новы синтаксіс. Аналізуючы якія-то з іх, можна пабачыць, як цей набір інструментаў дасяг ў своем сучасным стане — спачатку стаўшы болей точным, а потым значна быстрым.

Болей розумная інференція ў TypeScript 6

Кожны, хто запісваў скорочаны варыянт методу, а пасля бачыў, як параметр таямніча ператвараецца на any, разумеюць, насколькі раздражаючымі моглі быць старыя правіла інференціі у TypeScript. TypeScript 6 рашае гэту проблему, а таксама калькольку іншых недагэнаў у інференціі, якія прымусвалі разработчыкаў шукаць адпаведзі з гадоў.

Раней кожны функцыя, якая внутршняя чыню прыкладвала this, супадала з категоріяй „чутлівай да контексту“, што значыла, што кампайлер абоўсумова прыпіняў інференцію типу параметра — нават у тых случаях, калі this на самай працэ практычна не викорыстоўвалася ў тэле функцыі:

// Old behavior: 'user' silently became 'any'
const handlers = {
  onSave(user) {
    console.log(user.name); // no autocomplete, no error
  },
};

У TypeScript 6 кампляйзер спрацоўвае як контекстна чутлівы толькі тады, калі внутры ў функцыі дзейсна выкарыстоўваецца this. Якщо гэтага не выкарыстоўваецца, прыменяецца стандартная логіка адгадвання, і параметр атрымоўвае свой запланаванный тип, замест таго каб перайшаць на any:

// TypeScript 6: 'user' is correctly inferred from context
const handlers: Handlers = {
  onSave(user) {
    console.log(user.name); // fully typed
  },
};

Це выглядае як невялікая тэхнічная корекцыя, але яна мае значны патэнціял на вплыв на ўседзёны разработку, бальш таму, у кодавых базах React і Next.js, дзе методы об’ектаў і працоўнікі здачы падзеяў ёсць скрозу.

TypeScript 6 таксама прыносіць падтрымку декларацый using першага класу, якія формалізуюць явнае кераванне рэсурсамі. У змену таму, каб вручную абгортваць логіку чысткі ва ўпаковцы try/finally, можна дазволіць кампляйзеру аўтаматычна кераваць вываленнем рэсурсаў, калі значэнне выходзіць за межы свайго дыапазону:

function readConfig() {
  using file = openFile("./config.json"); // auto-disposed at scope end
  return JSON.parse(file.read());
}

Імпорты падпарадоў таксама становяцца чыстэйшымі. Прыменшук #/ тепер працюе через поле imports, чым можна ухіліцца ад дужаўых ланцаў стосавых шляхоў ../../../:

{
  "imports": {
    "#/*": "./src/*"
  }
}
import { formatCurrency } from "#/utils/currency";
// instead of: import { formatCurrency } from "../../../utils/currency";

Зменіліся таксама калькольныя значэння. Палітра target тепер калькольна як ES2023, а не як старая база ES3; палітра module калькольна як ESNext, а палітра moduleResolution — як bundler. Палітра types таксама калькольна як порожня маса, што не дазволяе TypeScript аўтаматычна сканаваць і заваносіць усе пакеты @types, якія ён можа знайсці. За словамы Microsoft, сама гэта змяна прыводзіць да павышэння часу складання на 20–50 процэнтав, таму перагляд вашага tsconfig.json є корыстным, нават якщо вы не маеце інтересу да впрыявання новых фічах языка.

У сукупнасці рэкамендацыі TypeScript 6 выглядзяюць так: абсалютна перапрацоўка всіх об’ектаў у вашай базе коду, якія маюць вельмі большую колькасць методаў, адтак якя можу безкоштовна павысіць рэбяткавасць типаў; выкарыстанне ключоўга using там, дзе вы працуяте з файламі, з’ўязкамі чы рэглерамі, якія патрабуюць адчысцення; не проста мовчкі спадчыяваць новыя стандартныя настройкі кампайляра — яшчэ і ясна ўстановіць іх у файле tsconfig.json, каб вашы намеры былі зрозумелы; а таксама спакою чакаць, што падазрэнняя на типы, якія прыносяць фреймворкі і бібліятэкі, такія як React, Redux чы інструменты Tailwind, адпавядаць гэтым змянам прыбліжна за наступныя тыдні. TypeScript 6 — гэта не тымчасовая версія; яна значна зменшае колькасць неспадзянак, якія вы сталкватеся з кожным днём у падзеі інферэнцыі типаў, і гэта сама по сабе ёсць дастатнім адказам для апгрэйда.

Полная перапрацоўка ў TypeScript 7

Як TypeScript 6 пасівалізав спосаб, якым кампайляр аналізуе типы, TypeScript 7 нацэлёўся на ўсё бол фундаментальную проблему — штоўкі працюе весь інструментальны комплекс. Microsoft цэлы кампайляр, сервіс мовы і супакоўваючыя інструменты перапісаў цэлкам на мове Go, заменіўшы самастойную рэалізацыю на JavaScript, якая працавала для TypeScript гады. Гэта не проста незначны апдэйт версіі — гэта вважаецца найбольшымі змянамі ў працэсавай скорасці за всю історыю мовы.

Кожны, хто стаяў і спаглядаў індыкатор загрузкі рэдагара, чакаючы на паведамленне пра адпаведнае памылку типу, зрозумее, на якую проблему спрямованы гэтыі перапіс.

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

Своія публікуемыя Microsoft крэтынгі даюць уявленне пра меру павышэння якасці. У кодбазе VS Code, якая складаецца з прыблізна 1,5 мільйона ліній коду, цэлы процес кампайлявання, які раней займаў або 125 секунд, тепер завершаецца за апоўну 10 секунд. Час, пакі ў рэдагары разгледзаецца першая памылка типу, зменіўся з прыблізна 17 секунд на менейш за 1,5 секунды. Вываранне памяці зменілася прыблізна на 18 процэнтов, а крахі сервера для обробкі мовы зменіліся на больш за 60 процэнтов. Гэтыя цифры таксама не ўсё ж такі суцэльна синтэтычныя — компаніі, укладзіце Slack, Figma, Google, Notion і Vercel, прыменялі новы кампайляр у рэальных проектах пры вырабоце, і адзвярнуліся, што павышэння якасці застаўся незменным пахавара ад крэтынгаў.

Для команд, які працуюць з React і Next.js, это пераходзіць у конкрэтныя ўседзённыя выгоды. У велікам манорепаце чаканне, пакуль tsc выкроіць несупаданне типаў, раней могло займаць калькі секунд; гэты час адліквідацыі значна зменшаецца за дапамогою кампайляра на базе Go:

// Before: waiting on tsc to catch this in a large monorepo could take seconds
interface UserCardProps {
  name: string;
  avatarUrl?: string;
  onSelect: (userId: string) => void;
}

function UserCard({ name, avatarUrl, onSelect }: UserCardProps) {
  // With TS7's native checker, this feedback loop is nearly instant
  return (
    <button onClick={() => onSelect(name)} className="rounded-lg p-2 hover:bg-slate-100">
      {avatarUrl && <img src={avatarUrl} alt={name} className="h-8 w-8 rounded-full" />}
      <span>{name}</span>
    </button>
  );
}

Велікія прыемплі Next.js з сотнямі компанентаў больш не спрыяюць тыповай перапрацоўцы як вузькам месту ў процесе CI, як гэта было раней. Проекты, створаныя з важкімі гэнерычнымі тыпамі, такімі як тые, што аб’еднваюць Tailwind і Redux, маюць значна быстрэйшую практычную перабудову. Автодаполненне ў рэдагарыі у велікіх манорепацях таксама стае набліжна болей рэакtyўным.

Перад апгрэйдам існуе калькі застережэнняя, якія варта адзначыць. Строгі режым тепер є стандартным, таму ранейшыя кодавесцы з менш строгімі правіламі можу выявіць новыя адказы. Канфігурацыі компілявання у старым формате, такія як es5, а таксама старэйшыя настройкі рашучага модуляў, больш не ёсць проста паведамленняяпра адказы — іх спрацоўваюць як серйозныя адказы. А такіму, калі API ў гэтым выданні є часткова стабільным, кожны фрэймворк чы средства, якія залежаць ад яго безпосередна, должны чакаць выходу TypeScript 7.1 пры апгрэйдзе.

Нічыя з гэтых змян не выклікае новай сынтаксісу чырастае граматыкі — TypeScript 7 створаны пераважна для рашэння проблемы з выконванасцю кампайляра, якая існуе вэлі гадоў. Якщо ваша команда працуе з большым кодавым базам на React чыра Next.js, гэтае выданне нарэшце робіць tsc менш прыкметным як ўсё тое, з чым трэба борцаваць. Як і праз будзья значныя змяны в інфраструктуре, цікава прабавіць яго спачатку на дапаможнай галузі; ваша CI-система будзе вам заўдзячна за такую абераглівасць.

Спадневана літэратура

  • Ролі «моста» TypeScript 6 у парадыграме пераходу да натывнага кампайляра TS 7 — Дазвольце дазнацца, як TypeScript 6 адкорэгуе стандартныя настройкі, процес развязвання модуляў і синтаксіс імпорта, каб падготавіць базы коду для быстрэйшага кампайляра TypeScript 7, створанага на мове Go.
  • Як працуе перапісванне TypeScript 7 на мове Go: прырост скорасці без змян у кодзе — Дазвольце дазнацца, як кампайляр TypeScript 7, створаны на мове Go, даёст у 8-12 разоў большую скорасць падчас компіляцыі, чаму такая архітектурная змена ўздоўжвае, і як безпечна апградаваць існуючыя проекты.