بررسی Generic در تایپ اسکریپت

در این مقاله قصد داریم تا اصول اولیه مربوط به generic در تایپ اسکریپت را باهم بررسی کنیم. همچنین در مورد نحوه استفاده از آن‌ها زمانی که برای برنامه ما مفید هستند صحبت خواهیم کرد.

موارد استفاده از Genericها

با یک مثال ساده شروع می‌کنیم، قصد داریم مقدار یک آرگومان ارسال شده را چاپ کنیم:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
function printData(data: number) {
console.log("data: ", data);
}
printData(2);
function printData(data: number) { console.log("data: ", data); } printData(2);
function printData(data: number) {
    console.log("data: ", data);
}

printData(2);

فرض کنید می‌خواهیم

printData
printDataرا به یک تابع عمومی‌تر تبدیل کنیم، به این صورت که می‌توانیم هر نوع آرگومان مانند boolean، string و یا number را به آن ارسال کنیم. بنابراین ممکن است فکر کنید رویکردی مانند روش زیر را دنبال خواهیم کرد:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
function printData(data: number | string | boolean) {
console.log("data: ", data);
}
printData(2);
printData("hello");
printData(true);
function printData(data: number | string | boolean) { console.log("data: ", data); } printData(2); printData("hello"); printData(true);
function printData(data: number | string | boolean) {
    console.log("data: ", data);
}

printData(2);
printData("hello");
printData(true);

اما ممکن است در آینده بخواهیم آرایه‌ای از اعداد را با استفاده از همان تابع چاپ کنیم. در این صورت تایپ‌ها افزایش می‌یابند و نگه‌داری همه آن‌ها سخت خواهد شد.

اینجا زمانی است که genericها مطرح می‌شوند.

Genericها چگونه در تایپ اسکریپت کار می‌کنند؟

genericها مانند متغیرهایی (به طور دقیق متغیرهای تایپ) هستند که تایپ، مثلا number، string و یا Boolean را به عنوان یک مقدار ذخیره می‌کنند. بنابراین، می‌توانیم مشکلی را که در بالا در مورد آن صحبت کردیم با استفاده از generic حل کنیم. به این صورت که:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
function printData<T>(data: T) {
console.log("data: ", data);
}
printData(2);
printData("hello");
printData(true);
function printData<T>(data: T) { console.log("data: ", data); } printData(2); printData("hello"); printData(true);
function printData<T>(data: T) {
    console.log("data: ", data);
}

printData(2);
printData("hello");
printData(true);

یک تفاوت جزئی در سینتکس مثال بالا وجود دارد:

  1. ما از یک متغیر تایپ در داخل
    <>
    <>بعد از نام تابع استفاده می‌کنیم
    <T>
    <T>
  2. سپس متغیر تایپ را به پارامتر
    data
    dataتخصیص می‌دهیم
    data: T
    data: T

در ادامه این تفاوت‌ها را بیشتر بررسی می‌کنیم.

برای استفاده از genericها باید از

<>
<> استفاده کنیم. سپس یک متغیر تایپ داخل
<>
<> تعیین می‌کنید. توسعه‌دهندگان معمولاً از
T
T،
X
Xو
Y
Yبرای این کار استفاده می‌کنند. اما بسته به ترجیح ما می‌تواند هر چیزی باشد.

سپس می‌توانیم همان نام متغیر را به عنوان تایپ به پارامتر تابع اختصاص دهیم. اکنون هر آرگومانی که به تابع ارسال می‌کنیم، infer می‌شود و نیازی به هاردکد کردن تایپ آن در جایی وجود ندارد.

حتی اگر یک آرایه از اعداد یا یک آبجکت به تابع

printData
printDataارسال کنیم، همه چیز به درستی و بدون مشکل نمایش داده می‌شود:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
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<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<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 });

مثال دیگری را ببینیم:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
function printData<X,Y>(data1: X, data2: Y) {
console.log("Output is: ", data1, data2);
}
printData("Hello", "World");
printData(123, ["Hi", 123]);
function printData<X,Y>(data1: X, data2: Y) { console.log("Output is: ", data1, data2); } printData("Hello", "World"); printData(123, ["Hi", 123]);
function printData<X,Y>(data1: X, data2: Y) {
    console.log("Output is: ", data1, data2);
}

printData("Hello", "World");
printData(123, ["Hi", 123]);

در مثال بالا ما ۲ آرگومان به تابع

printData
printData ارسال کرده و از
X
Xو
Y
Yبرای مشخص کردن تایپ‌های هر دو پارامتر استفاده کردیم.
X
X به مقدار اول آرگومان و
Y
Y به مقدار دوم آرگومان اشاره دارد.

در این مثال نیز تایپ

data1
data1و
data2
data2به صراحت مشخص نشده است زیرا تایپ اسکریپت inference تایپ را با کمک generic کنترل می‌کند.

نحوه استفاده از Genericها با Interfaceها

ما حتی می‌توانیم از genericها با interfaceها استفاده کنیم. در ادامه بررسی می‌کنیم که این کار چگونه انجام می‌شود:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
function printData<X,Y>(data1: X, data2: Y) {
console.log("Output is: ", data1, data2);
}
printData("Hello", "World");
printData(123, ["Hi", 123]);
function printData<X,Y>(data1: X, data2: Y) { console.log("Output is: ", data1, data2); } printData("Hello", "World"); printData(123, ["Hi", 123]);
function printData<X,Y>(data1: X, data2: Y) {
    console.log("Output is: ", data1, data2);
}

printData("Hello", "World");
printData(123, ["Hi", 123]);

در قطعه کد بالا

<string, number>
<string, number>به رابط
UserData
UserDataارسال می‌شود. به این ترتیب،
UserData
UserData تبدیل به یک interface با قابلیت استفاده مجدد می‌شود که در آن هر تایپ داده‌ای را می‌توانیم بسته به نیازی که داریم اختصاص دهیم.

در این مثال،

name
nameو
rollNo
rollNoهمیشه به ترتیب
string
stringو
number
numberخواهند بود. اما این مثال نشان می‌دهد که چگونه می‌توانیم از generic ها به همراه interfaceها در تایپ اسکریپت استفاده کنیم.

دیدگاه‌ها:

افزودن دیدگاه جدید