Апгрэйд кодбазы на React да TypeScript 6.0: Чаго зламаецца першым
Як строгейшыя стандартныя значэння, паследжванне методаў, імпорты падшляхоў #/ і типы Temporal у TypeScript 6.0 паўтараюцца на прыемнасці React-прыёмкі, а таксама спіс пунктав для безпечнага апдэйта.
Крыніцы: TypeScript 6.0 for React Developers: What Actually Changed
Большасць апдэйтаў кампайляра застаецца непазначанымі. TypeScript 6.0 — адзін з існуючых выключэнняў: гэта пасляпядны выпуск, створаны на аснове первіснага кампайляра JavaScript, і ён гэтым чынам служыць пераважна для падготовкі кодавых баз да версіі TypeScript 7, якая будзе аднойчы працаваць на базе языка Go. Таму ён прыносіць менш функцый і больш змян, якія выявляюць ўжыткавесныя проблемы. У гэтым кіясе описваецца, як саме будзе відчуватыся кодавая база на React, і ён завершаецца спісам пунктав для апдэйта. Чым саме 6.0 спадчынае пераходу да натыўнага кампайляра, можна дазнацца за роллю TypeScript 6 як моста на шляху да натыўнага кампайляра TS 7.
Спачатку — строгейшыя стандартныя настройкі
TypeScript 6.0 паўтарычна увялічвае строгі режым, выкарыстоўвае ES-модулі і перакладае стандартную мету на es2025. Праекты, якія явна задаюць усе параметры, не падвергаюцца вплыву; праекты, якія спакоюваліся на старых, менш строгіх значэннях, пачуць хвалю новых адзінакоў. У коде React зазвычай страждаюць старэйшыя компаненты: пропсы з нечыстаю типаваннем, функціі-обрабнікі з неявнымі параметрамі any, рэфы, якія могу быць null, а таксама функцыя useState() без параметра типу. Гэта не ўскладнення, а давялеглія неодназначнасці, якія тепер фіксуюцца.
es3 і es5 цялі таксама ўстарэлі, таму мінімальны стандарт стае es2015. Для багатоў прыкладаў аплікацый на React гэта мало каштуе, таму што Babel, SWC чыста esbuild адпаведна перакладаюць синтаксіс, а tsc толькі пераглядае типы, але пераканайцеся ў гэтым пры падборы падтрымкі браузераў. Здзейсніце апгрэйд на адной з окремых галузей з полным будаваннем і тэстамі; змена стандартных налашчанняў кампайляра ў пятніцу апоўдні — гарантаваны спосаб згубіць вякенд.
Аднаковая інферэнція для функцый у стыле методаў
Іншы спосаб выліквітання проблемы стосуецца ситуацыі, калі функцыя вважаецца „чулай да контексту“, тое ў значэнні, што типы яе параметраў павінны бацца ў контексте, прычаму можна продаваць вывод. У версіі 6.0 выраз function або скрацення метода спрацьоввае такім чынам толькі тады, калі ён фактычна выкарыстоўвае this. Раней выбір синтаксісу метода заместо функцыі-стрэлкі мог уплываць на генерычны вывод, нават калі this не быў ужоўваны. Наведзены выкладак сумешчае оба стылі:
// Before: inconsistent inference depending on syntax
const useCounter = (initial) => {
const [count, setCount] = useState(initial);
// this pattern used to infer differently than an arrow fn
const increment = function () {
setCount((c) => c + 1);
};
return { count, increment };
};
Раней калебачкае выкананне, такое як increment, магло выважвацца інакш, чым адпаведная функцыя-стрэлка, і ў большых выкладаках такая разніца магла прызвесці да таго, што слабейшы тип будзе пераданы вызывачам. Тепер синтаксіс, які вы выбіраеце для калебачкаў і вярнуваных дапаможных функцый, больш не змінюе рэзультуючыя типы, што усунула плутанне, вызванае запытамі „Чаму этот калебачка не перакананы?“
Адаптаванне імпортаў з прыфіксам #/
Імпорты падшляхоў у Node визначаюць прыватныя аліясы ў поле imports файла package.json, і TypeScript 6.0 падтрымлівае прыфікс #/ там, што падабаецца да аліясоў корневага рэв’ю, якія часта викорыстоўваюць бандлеры. Заявіце це супарадненне аднойчы:
{
"imports": {
"#/*": "./src/*"
}
}
Потым компаненты імпортуюць з корню проекта, а не після лічбы сегментоў ../:
// No more relative path spaghetti in deeply nested components
import { useAuth } from "#/hooks/useAuth";
import { Button } from "#/components/ui/Button";
Пакалі аліяс знаходзіцца ў package.json, а не толькі ў рэгламентах paths файла tsconfig.json, Node і TypeScript разв’язваюць яго аднакова, без дадатковых плагінаў. Гэта прымае чыннасць толькі ў режымах разв’язвання, якія чытаюць імпорты з package.json, такіх як nodenext або bundler.
Тэмпаральныя типы ўключаныя з самага пачатку
TypeScript 6.0 адаптавае деклараціі для API Temporal, які вже нашліся на заключным этапе стандартизацыі TC39. Команды, якія ствараюць інтерфейсы для планавання, броніравання чыста панелей керування, можаць выкарыстоўваць Temporal.PlainDate чыста Temporal.ZonedDateTime без дапамогі дадатковых пакетаў, замест таго каб прымусваць выкарыстоўванне Date. Аднак гэтыя типы не забезпечваюць падтрымкі ў часе выканання: пераканайцеся, чы роўнэйшыя браузеры чыста версіі Node падтрымляюць іх, і за неабходнасці дадзіце поліфіл.
Чы трэба апгрэйдаваць зараз?
Так, намерова. Команда TypeScript прыступіла да выпуску 6.0 як стабільнага апгрэйда, але змены ў яго внутранісці рэальныя:
- Адрабоўваце файл
tsconfig.jsonі зафіксаваць усе опцыі, ад яых вы залежыце. - Ліквідаваць новыя памылкі строгага режыму ў старэйшых компонентах, а не проста маскаваць іх за дапамогою
any. - Убедзіцеся, які інструмент выкарыстоўваецца для знижэння версіі чыста якой цэльвай версіі ён неабходны.
noImplicitOverride, каб члены, якія перакрываюцца, вымагалі наявнасці атрыбута override.Заключанне
TypeScript 6.0 не змяні спосабу напісання коду на React, але ён адкрывае проблемы, якія раней хавалі слабкія стандартныя настройкі. Їх рашэнне зараз, па вашаму графіку, ў дзесяткі разоў дышэвей, чым рашаць іх пазней у годзе, калі ўжо будзе пераход на версію 7, і тады гэты пераход стане пераважна праблемай карыстоўнасці.