در این مقاله قصد داریم تا اصول اولیه مربوط به generic در تایپ اسکریپت را باهم بررسی کنیم. همچنین در مورد نحوه استفاده از آنها زمانی که برای برنامه ما مفید هستند صحبت خواهیم کرد.
با یک مثال ساده شروع میکنیم، قصد داریم مقدار یک آرگومان ارسال شده را چاپ کنیم:
function printData(data: number) { console.log("data: ", data); } printData(2);
فرض کنید میخواهیم printData
را به یک تابع عمومیتر تبدیل کنیم، به این صورت که میتوانیم هر نوع آرگومان مانند boolean، string و یا number را به آن ارسال کنیم. بنابراین ممکن است فکر کنید رویکردی مانند روش زیر را دنبال خواهیم کرد:
function printData(data: number | string | boolean) { console.log("data: ", data); } printData(2); printData("hello"); printData(true);
اما ممکن است در آینده بخواهیم آرایهای از اعداد را با استفاده از همان تابع چاپ کنیم. در این صورت تایپها افزایش مییابند و نگهداری همه آنها سخت خواهد شد.
اینجا زمانی است که genericها مطرح میشوند.
genericها مانند متغیرهایی (به طور دقیق متغیرهای تایپ) هستند که تایپ، مثلا number، string و یا Boolean را به عنوان یک مقدار ذخیره میکنند. بنابراین، میتوانیم مشکلی را که در بالا در مورد آن صحبت کردیم با استفاده از generic حل کنیم. به این صورت که:
function printData<T>(data: T) { console.log("data: ", data); } printData(2); printData("hello"); printData(true);
یک تفاوت جزئی در سینتکس مثال بالا وجود دارد:
<>
بعد از نام تابع استفاده میکنیم <T>
data
تخصیص میدهیم data: T
در ادامه این تفاوتها را بیشتر بررسی میکنیم.
برای استفاده از genericها باید از <>
استفاده کنیم. سپس یک متغیر تایپ داخل <>
تعیین میکنید. توسعهدهندگان معمولاً از T
، X
و Y
برای این کار استفاده میکنند. اما بسته به ترجیح ما میتواند هر چیزی باشد.
سپس میتوانیم همان نام متغیر را به عنوان تایپ به پارامتر تابع اختصاص دهیم. اکنون هر آرگومانی که به تابع ارسال میکنیم، infer میشود و نیازی به هاردکد کردن تایپ آن در جایی وجود ندارد.
حتی اگر یک آرایه از اعداد یا یک آبجکت به تابع printData
ارسال کنیم، همه چیز به درستی و بدون مشکل نمایش داده میشود:
function printData<T>(data: T) { console.log("data: ", data); } printData(2); printData("hello"); printData(true); printData([1, 2, 3, 4, 5, 6]); printData([1, 2, 3, "hi"]); printData({ name: "Ram", rollNo: 1 });
مثال دیگری را ببینیم:
function printData<X,Y>(data1: X, data2: Y) { console.log("Output is: ", data1, data2); } printData("Hello", "World"); printData(123, ["Hi", 123]);
در مثال بالا ما ۲ آرگومان به تابع printData
ارسال کرده و از X
و Y
برای مشخص کردن تایپهای هر دو پارامتر استفاده کردیم. X
به مقدار اول آرگومان و Y
به مقدار دوم آرگومان اشاره دارد.
در این مثال نیز تایپ data1
و data2
به صراحت مشخص نشده است زیرا تایپ اسکریپت inference تایپ را با کمک generic کنترل میکند.
ما حتی میتوانیم از genericها با interfaceها استفاده کنیم. در ادامه بررسی میکنیم که این کار چگونه انجام میشود:
function printData<X,Y>(data1: X, data2: Y) { console.log("Output is: ", data1, data2); } printData("Hello", "World"); printData(123, ["Hi", 123]);
در قطعه کد بالا <string, number>
به رابط UserData
ارسال میشود. به این ترتیب، UserData
تبدیل به یک interface با قابلیت استفاده مجدد میشود که در آن هر تایپ دادهای را میتوانیم بسته به نیازی که داریم اختصاص دهیم.
در این مثال، name
و rollNo
همیشه به ترتیب string
و number
خواهند بود. اما این مثال نشان میدهد که چگونه میتوانیم از generic ها به همراه interfaceها در تایپ اسکریپت استفاده کنیم.
دیدگاهها: