Посочване на проблема Тъй като typescript расте и набира популярност напоследък, все повече разработчици на javascript оценяват безопасността на типа. Списъкът с функции, предоставяни от Typescript, е огромен и може да е огромен, така че в тази публикация ще се съсредоточа върху една от тях, която е лесна за разбиране и има чудесно практическо въздействие. Да започнем с един пример. Представете си, че разработвате приложение с много потребителски роли. Доста обичайно е едно приложение да се използва от различни потребители, нали? Точните роли не са особено важни тук, но да кажем, че те са , и . В typescript можем да декларираме потребители, притежаващи тези роли, както следва: admin consumer guest 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: "johnsmith@examplemail.com", 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 свойства, които могат или не могат да бъдат свързани с конкретен потребител.