Подобрете изживяването си на разработчици с динамични типове

Здравейте всички! Тази публикация е базирана на последния разговор на Жан Себастиан на Strapi Conf 2023. Ще дам връзка към видеото в края на публикацията.

JS е бекенд инженер, специализиран в опита на разработчиците в Strapi. Той също обича TypeScript.

Махни го, JS.

Здравейте всички! Аз съм Жан Себастиан и съм развълнуван да споделя някои прозрения за това как можете да подобрите изживяването си за разработчици, особено когато работите с приложения със силно динамични структури на съдържание, използващи TypeScript. Така че, без допълнително обожание, нека навлезем.

Защо TypeScript?

TypeScript е мощен инструмент, който подобрява опита на разработчиците с множество функционалности. Те включват и не се ограничават до функции, гарантиращи безопасност на типа, предлагащи подобрен IntelliSense и опростяващи навигацията през сложни кодови бази.

Например,

  • Безопасност на типа: TypeScript подпомага ранното идентифициране на грешки чрез проверки по време на компилиране и линтинг в реално време в интегрирани среди за разработка (IDE).
  • Изследване на кодова база: Анотацията на типове и функциите за прескачане към декларация са невероятно полезни за четимост и проследимост на кода.
  • IntelliSense: TypeScript извежда кодирането на следващото ниво, като предлага насоки в реално време, започвайки от автоматично довършване до предложение за код.

Мислете за TypeScript като за съдия в игра. Той чете правилата, т.е. типовете и конфигурациите, предоставени от разработчиците и съответно извиква предупреждения, грешки и излъчва кодове.

Комбинацията от тях прави TypeScript огромен актив за подобряване на производителността, като същевременно намалява разходите за разработка чрез елиминиране на повечето грешки при изпълнение и проблеми с изтичането на кодовата база.

Въпреки това, ако приемем, че TypeScript е магическа пръчица, преобразуването на JavaScript в TypeScript чрез просто преименуване би било наивно.

TypeScript е страхотен...през повечето време.

TypeScript работи много добре по отношение на intellisense или проверка на типа, защото разчита на източника на Truth, типовете, дефинирани от разработчиците.

Разработчиците са склонни да познават много добре структурите и моделите на приложенията; например, някой, който разработва уебсайт за електронна търговия, вероятно знае, че ще се нуждае от модел, който да представя проект, марка и количка, както и как да ги свърже чрез създаване на връзки и връзка, по същия начин, някой, който прави блог знаят, че имат работа с етикети и автори на публикации.

Машинописът е само реферът; той чете правилата, написани от разработчиците.

Тук, в Strapi, имаме интересно предизвикателство. Не знаем предварително структурата на съдържанието или нещо точно за нашия модел на потребителски приложения.

Така че не можем да предполагаме и генерираме типове предварително, тъй като възможностите ще бъдат безкрайни, тъй като като потребител на Strapi можете да създавате всякакви типове съдържание, от които се нуждае вашето приложение за вашия конкретен случай на употреба.

Създаването на споделени типове е предизвикателство. Как ще работи TypeScript, когато моделите са силно непредвидими?

Първо, нека да разгледаме пример за това кога извличаме данни. Целта е да се създаде обща функция, която отправя заявки към даден модел, за да извлече свързаното с него съдържание от базата данни.

Въпреки че горният код е точен от гледна точка на Typescript, той не ни помага много при разработването на нашето приложение, защото тук имаме свободна проверка на типа, нямаме автоматично довършване за наличните потребителски идентификатори или каквато и да е информация за стойностите, които можем да очакваме в отговор.

Това прави изживяването на разработчиците малко странно и вероятно ще трябва да направите много кастинг, за да адаптирате типовете към вашия проект.

За да поправим това, ще ни трябва достъп до някаква база данни с машинопис или регистър на всички модели, които съществуват в нашето външно приложение и техните uids.

Можем да променим нашия код на следния.

и това е мястото, където се намесват регистрите от динамичен тип.

Регистри с динамичен тип

Регистрите от динамичен тип са обикновени интерфейси, декларирани в споделен модул, който магазинът на Strapi би експортирал.

Въпреки че е празен по подразбиране, ние решихме да използваме възможностите за сливане и разширяване на интерфейса, за да позволим на приложението или приставката на Strapi да добавя нови дефиниции на типове към тези интерфейси.

Например, ако използвате модел на статия във вашето приложение Strapi, можете да го регистрирате в споделения интерфейс, така че да може да бъде взет от Strapi, когато използвате неговия вътрешен API.

По този начин имаме база данни от споделени компоненти, като моделите в нашия случай, които се използват от вътрешни API, докато се попълват и допълват от външни участници.

В крайна сметка, това ни позволява да пишем генерични API, базирани на абстрактни модели и обекти от страна на Strapi, като същевременно предоставяме пълната мощност на автоматичното довършване на шрифта и IntelliSense в потребителски проекти, които разширяват регистрите на типове.

Ето дизайна на това, което току-що обяснихме; както можете да видите, Strapi излага модул от споделени регистри, съдържащ много интерфейси.

Модулът и неговите интерфейси след това се разширяват от външни участници като приложението или плъгин и след това могат да се използват от всеки за създаване на персонализирани APS или просто референтни типове.

Въпреки че това решава проблема с наличието на точни типове и разработването на мощни въведени API, това не е много мащабируемо решение.

Да се ​​налага да пишете сложни типове и да увеличавате ръчно много споделени регистри за едно приложение е твърде много за изискване и в крайна сметка това само ще създаде разочарование.

За съжаление, този ръчен процес не е мащабируем поради включената сложност, което води до лош опит на разработчиците. Но има решение — автоматично генериране на типове.

Автоматично генериране на типове.

Състои се от това, че Strapi чете вашите модели на приложения, за да генерира типове, които след това ще увеличат динамичните регистри.

Но първо, нека определим нашите нужди.

  1. Трябва да се направи програмно.
  2. Трябва да създава типове с буквални стойности.
  3. Трябва да може да се поддържа.

И трябва да избягва манипулиране на низове, като конкатенация и т.н., което ни накара да открием TypeScript Factory API.

TypesScript Factory API

Фабричният API на TypeScript е набор от помощни средства, създадени за генериране и манипулиране на възли на TypeScript AST. След това възлите могат да се използват за излъчване на дефиниции в изходния файл.

Трансформирахме нашите модели във възли на машинописи, използвайки фабричния API, създадохме фалшив изходен файл от същата дефиниция и след това накрая излъчихме файлове с дефиниции на машинописи, съдържащи разширението на регистъра и свързани типове модели.

Тук можете да видите какво се случва, когато ръчно задействаме генериране на типове, докато то създава типове за типове съдържание и компоненти на приложението Strapi.

И тук можем да видим част от това, което се излъчва.

Можем да наблюдаваме разширяването на модула за магазин и регистъра на компонентите, който се разширява с различни модели.

В крайна сметка намерихме заобиколно решение, за да се насладим на всички предимства на TypeScript, когато работим със силно динамични структури на съдържание.

Тук можем да видим, че предишният ни пример работи перфектно с генерираните типове и разширените регистри.

Надявам се, че сте харесали тази публикация от JS и ще се видим следващия път.

„Вижте разговора на JS тук“