paint-brush
Силата на дискриминираните синдикати в TypeScriptот@tokenvolt
242 показания

Силата на дискриминираните синдикати в TypeScript

от Oleksandr Khrustalov4m2024/10/05
Read on Terminal Reader

Твърде дълго; Чета

Тази история прави преглед на основите на дискриминираните съюзи в TypeScrips. Използвам ги доста често в разработката си, така че ще разгледаме определен пример как да ги приложим.
featured image - Силата на дискриминираните синдикати в TypeScript
Oleksandr Khrustalov HackerNoon profile picture

Посочване на проблема

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


Да започнем с един пример. Представете си, че разработвате приложение с много потребителски роли. Доста обичайно е едно приложение да се използва от различни потребители, нали? Точните роли не са особено важни тук, но да кажем, че те са admin , consumer и guest . В typescript можем да декларираме потребители, притежаващи тези роли, както следва:


 type Admin = {} type Consumer = {} type Guest = {}


Сега нека разгледаме набор от атрибути, които има всяка потребителска роля. Обикновено те са email , firstName и lastName или нещо подобно. Но изчакайте, потребителите Guest вероятно няма да имат такива (все пак са гости), така че нека просто оставим този тип празен за сега.


 type Admin = { firstName: string lastName: string email: string } type Consumer = { firstName: string lastName: string email: string } type Guest = {}


Потребителят на приложение може да има само една роля. Начинът да се представи това чрез типове е да се използва тип union .


 type User = Admin | Consumer | Guest


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


 type Admin = { firstName: string lastName: string email: string numberOfInvitesLeft: number // <-- added }


За да направим нещата по-интересни и по-близки до реално приложение, нека добавим свойство, изключително за тип Consumer .


 type Consumer = { firstName: string lastName: string email: string premium: boolean // <-- added }


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


 const doSomethingBasedOnRole = (user: User) => { // how do you check here that user is really an admin if (user) { // ...and do something with the `numberOfInvitesLeft` property? } }


Единият вариант е да проверите съществуването на имота.


 const doSomethingBasedOnRole = (user: User) => { if (user && user.numberOfInvitesLeft) { // safely access `numberOfInvitesLeft` property } }


Но това е досадно и не мащабируемо решение. И какво да направите, когато `numberOfInvitesLeft` стане незадължително свойство?

Представяне на дискриминирани видове съюзи

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


 type Admin = { firstName: string lastName: string email: string numberOfInvitesLeft: number role: "admin" // <-- added } type Consumer = { firstName: string lastName: string email: string role: "consumer" // <-- added } type Guest = { role: "guest" // <-- added }


Забележете как поставям конкретен низ като тип; това се нарича тип низов литерал . Това, което ви дава, е, че сега можете да използвате оператори на родния JS език, напр. switch case , if , else за да разграничите ролята.


 const user: Admin = { firstName: "John", lastName: "Smith", email: "[email protected]", numberOfInvitesLeft: 3, role: "admin", } const doSomethingBasedOnRole = (user: User) => { if (user.role === "admin") { // now typescript knows that INSIDE of this block user is of type `Admin` // now you can safely call `user.numberOfInvitesLeft` within this block } }


Същото важи и за оператор за превключване на случай.


 // ... const doSomethingBasedOnRole = (user: User) => { switch (user.role) { case "admin": { // now typescript knows that INSIDE of this block user is of type `Admin` // now you can safely call `user.numberOfInvitesLeft` within this block } case "consumer": { // do something with a `Consumer` user // if you try to call `user.numberOfInvitesLeft` here, TS compiler errors in // // "Property 'numberOfInvitesLeft' does not exist on type 'Consumer'." // } } }


Ползите от дискриминираните типове обединения са очевидни, тъй като проверката на типа се основава на изрично свойство на ролята, а не на ad-hoc свойства, които могат или не могат да бъдат свързани с конкретен потребител.

L O A D I N G
. . . comments & more!

About Author

Oleksandr Khrustalov HackerNoon profile picture
Oleksandr Khrustalov@tokenvolt
Software Developer (Web)

ЗАКАЧВАЙТЕ ЕТИКЕТИ

ТАЗИ СТАТИЯ Е ПРЕДСТАВЕНА В...