همانطور که تایپ اسکریپت اخیراً در حال رشد و محبوبیت است، توسعه دهندگان جاوا اسکریپت بیشتر و بیشتر از ایمنی نوع قدردانی می کنند. لیست ویژگی هایی که 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: "[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 } }
همین امر در مورد عبارت switch case نیز صدق می کند.
// ... 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'." // } } }
مزایای انواع اتحادیههای تبعیضآمیز آشکار است زیرا بررسی نوع بر اساس ویژگی نقش صریح است و نه بر ویژگیهای موقتی که ممکن است به یک کاربر خاص مرتبط باشد یا نباشد.